Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add int_as_bits and int_as_capabilities converters #434

Merged
merged 1 commit into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions asusrouter/tools/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,50 @@ def handle_none_content(content: Optional[_T], default: Optional[_T]) -> Optiona
return content


def int_as_bits(value: int) -> list[bool]:
"""Convert an integer to a list of bits."""

if not isinstance(value, int):
return []

# Negative values are not supported
if value < 0:
return []

# Zero is a special case
if value == 0:
return [False]

return [bool(value & (1 << i)) for i in range(value.bit_length())]


def int_as_capabilities(value: int, capabilities: Type[Enum]) -> dict[Enum, bool]:
"""Convert an integer to a dict of capabilities."""

# Check if the capabilities is an enum
if not is_enum(capabilities) or not isinstance(value, int):
return {}

# Convert the value to a list of bits
bits = int_as_bits(value)

result = {}

# For each capability in the capabilities
# Considering key as a capability name and value as a capability bit
for capability in capabilities:
# Check that the capability is an integer
if not isinstance(capability.value, int):
continue

# Check if the bit is set
result[capability] = (
bits[capability.value] if capability.value < len(bits) else False
)

return result


def is_enum(v) -> bool:
"""Check if the value is an enum."""

Expand Down
77 changes: 77 additions & 0 deletions tests/tools/test_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,83 @@ def test_get_enum_key_by_value():
converters.get_enum_key_by_value(EnumForTest, 3)


@pytest.mark.parametrize(
("content", "result"),
[
(0, [False]),
(1, [True]),
(2, [False, True]),
(3, [True, True]),
(10, [False, True, False, True]),
# Test with negative integers and non-integer input
(-1, []),
("string", []),
(None, []),
],
)
def test_int_as_bits(content, result):
"""Test int_as_bits method."""

assert converters.int_as_bits(content) == result


# Define a test Enum
class Capabilities(Enum):
"""Capabilities enum."""

CAPABILITY1 = 0
CAPABILITY2 = 1
CAPABILITY3 = 2
CAPABILITY4 = 3
CAPABILITY5 = "not an int"


@pytest.mark.parametrize(
("value", "capabilities", "result"),
[
(
0,
Capabilities,
{
Capabilities.CAPABILITY1: False,
Capabilities.CAPABILITY2: False,
Capabilities.CAPABILITY3: False,
Capabilities.CAPABILITY4: False,
},
),
(
1,
Capabilities,
{
Capabilities.CAPABILITY1: True,
Capabilities.CAPABILITY2: False,
Capabilities.CAPABILITY3: False,
Capabilities.CAPABILITY4: False,
},
),
(
10,
Capabilities,
{
Capabilities.CAPABILITY1: False,
Capabilities.CAPABILITY2: True,
Capabilities.CAPABILITY3: False,
Capabilities.CAPABILITY4: True,
},
),
# Wrong input
(None, Capabilities, {}),
("string", Capabilities, {}),
(15, "not an enum", {}),
(15, None, {}),
],
)
def test_int_as_capabilities(value, capabilities, result):
"""Test int_as_capabilities method."""

assert converters.int_as_capabilities(value, capabilities) == result


def test_is_enum():
"""Test is_enum method."""

Expand Down