Skip to content

Commit 9ee7f01

Browse files
committed
feat: Add from_any_optional method to CodeMapping for flexible enum resolution with corresponding tests.
1 parent 7a61bfa commit 9ee7f01

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

roborock/data/code_mappings.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,30 @@ def from_name(cls, name: str) -> Self:
100100
return member
101101
raise ValueError(f"{name} is not a valid name for {cls.__name__}")
102102

103+
@classmethod
104+
def from_any_optional(cls, value: str | int) -> Self | None:
105+
"""Resolve a string or int to an enum member.
106+
107+
Triest to lookup by enum name, string value, or integer code
108+
and returns None if no match is found.
109+
"""
110+
# Try enum name lookup (e.g. "SEEK")
111+
try:
112+
return cls.from_name(str(value))
113+
except ValueError:
114+
pass
115+
# Try DP string value lookup (e.g. "dpSeek")
116+
try:
117+
return cls.from_value(str(value))
118+
except ValueError:
119+
pass
120+
# Try integer code lookup (e.g. "11")
121+
try:
122+
return cls.from_code(int(value))
123+
except (ValueError, TypeError):
124+
pass
125+
return None
126+
103127
@classmethod
104128
def keys(cls) -> list[str]:
105129
"""Returns a list of all member values."""

tests/data/test_code_mappings.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ def test_invalid_from_value() -> None:
5252
B01_Q10_DP.from_value("invalid_value")
5353

5454

55+
@pytest.mark.parametrize(
56+
"input, expected",
57+
[
58+
("START_CLEAN", B01_Q10_DP.START_CLEAN),
59+
("start_clean", B01_Q10_DP.START_CLEAN),
60+
("dpStartClean", B01_Q10_DP.START_CLEAN),
61+
(201, B01_Q10_DP.START_CLEAN),
62+
("PAUSE", B01_Q10_DP.PAUSE),
63+
("pause", B01_Q10_DP.PAUSE),
64+
("dpPause", B01_Q10_DP.PAUSE),
65+
(204, B01_Q10_DP.PAUSE),
66+
("STOP", B01_Q10_DP.STOP),
67+
("stop", B01_Q10_DP.STOP),
68+
("dpStop", B01_Q10_DP.STOP),
69+
(206, B01_Q10_DP.STOP),
70+
("invalid_value", None),
71+
(999999, None),
72+
],
73+
)
74+
def test_from_any_optional(input: str | int, expected: B01_Q10_DP | None) -> None:
75+
"""Test from_name method."""
76+
assert B01_Q10_DP.from_any_optional(input) == expected
77+
78+
5579
def test_homedata_product_unknown_category():
5680
"""Test that HomeDataProduct can handle unknown categories."""
5781
data = {

0 commit comments

Comments
 (0)