Repository: trag1c/crossandra (language: python)

Issue:
Add `RuleGroup.apply`
Should try applying the rules in order until a match is found


Discussion / hints:

Fix patch:
diff --git a/crossandra/rule.py b/crossandra/rule.py
index 373ac96..5cc6a35 100644
--- a/crossandra/rule.py
+++ b/crossandra/rule.py
@@ -122,6 +122,16 @@ class RuleGroup:
 
     rules: tuple[Rule[Any], ...]
 
+    def apply(self, target: str) -> tuple[Any | str | Ignored, int] | NotApplied:
+        """
+        Applies the rules in the group to the target string. Returns the
+        result of the first rule that matches, or `NotApplied` if none do.
+        """
+        for rule in self.rules:
+            if (result := rule.apply(target)) is not NOT_APPLIED:
+                return result
+        return NOT_APPLIED
+
     def __iter__(self) -> Iterator[Rule[Any]]:
         yield from self.rules
 


Test patch:
diff --git a/tests/test_common.py b/tests/test_common.py
index b4a33e7..590f94e 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -244,39 +244,39 @@ def test_signed_float(string: str, result: RuleResult) -> None:
 
 
 def test_number() -> None:
-    assert Crossandra(rules=[common.NUMBER]).tokenize("1.0") == [1.0]
+    assert common.NUMBER.apply("1.0") == (1.0, 3)
 
 
 def test_signed_number() -> None:
-    assert Crossandra(rules=[common.SIGNED_NUMBER]).tokenize("-1.0") == [-1.0]
+    assert common.SIGNED_NUMBER.apply("-1.0") == (-1.0, 4)
 
 
 @pytest.mark.parametrize(
     ("string", "result"),
-    [("1", [1]), ("-1", [-1]), ("+1", [1])],
+    [("1", (1, 1)), ("-1", (-1, 2)), ("+1", (1, 2))],
 )
-def test_any_int(string: str, result: list[int]) -> None:
-    assert Crossandra(rules=[common.ANY_INT]).tokenize(string) == result
+def test_any_int(string: str, result: RuleResult) -> None:
+    assert common.ANY_INT.apply(string) == result
 
 
 @pytest.mark.parametrize(
     ("string", "result"),
-    [("1.0", [1.0]), ("-1.0", [-1.0]), ("+1.0", [1.0])],
+    [("1.0", (1.0, 3)), ("-1.0", (-1.0, 4)), ("+1.0", (1.0, 4))],
 )
-def test_any_float(string: str, result: list[float]) -> None:
-    assert Crossandra(rules=[common.ANY_FLOAT]).tokenize(string) == result
+def test_any_float(string: str, result: RuleResult) -> None:
+    assert common.ANY_FLOAT.apply(string) == result
 
 
 @pytest.mark.parametrize(
     ("string", "result"),
     [
-        ("1", [1]),
-        ("-1", [-1]),
-        ("+1", [1]),
-        ("1.05", [1.05]),
-        ("-1.05", [-1.05]),
-        ("+1.05", [1.05]),
+        ("1", (1, 1)),
+        ("-1", (-1, 2)),
+        ("+1", (1, 2)),
+        ("1.05", (1.05, 4)),
+        ("-1.05", (-1.05, 5)),
+        ("+1.05", (1.05, 5)),
     ],
 )
-def test_any_number(string: str, result: list[int | float]) -> None:
-    assert Crossandra(rules=[common.ANY_NUMBER]).tokenize(string) == result
+def test_any_number(string: str, result: RuleResult) -> None:
+    assert common.ANY_NUMBER.apply(string) == result