home · contact · privacy
More code clean-up around message parsing.
authorChristian Heller <c.heller@plomlompom.de>
Sun, 23 Nov 2025 22:11:51 +0000 (23:11 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Sun, 23 Nov 2025 22:11:51 +0000 (23:11 +0100)
src/ircplom/msg_parse_expectations.py

index 5b622e9d2cf1359478dbf0876627ca395bba22d2..93ce1decd2759de15c2899dcc0332230d9d24ac1 100644 (file)
@@ -86,9 +86,18 @@ class _MsgParseExpectation:
                  bonus_tasks: tuple[str, ...] = tuple()
                  ) -> None:
         self.verb = verb
-        self.source = _TokenExpectation.from_(source)
-        self.params = tuple(_TokenExpectation.from_(param) for param in params)
-        self.bonus_tasks = tuple(_Code.from_(item) for item in bonus_tasks)
+        self._fields = tuple(_TokenExpectation.from_(guide)
+                             for guide in (source,) + params)
+        tasks: dict[_Command, list[str]] = {}
+        for code in (tuple(exp_field.code for exp_field in self._fields)
+                     + tuple(_Code.from_(item) for item in bonus_tasks)):
+            for cmd in code.commands:
+                tasks[cmd] = tasks.get(cmd, []) + [code.tok_name]
+        self._harvest_invariables = {'_verb': self.verb, '_tasks': tasks}
+
+    @property
+    def _params(self) -> tuple[_TokenExpectation, ...]:
+        return self._fields[1:]
 
     def parse_msg(self,
                   msg: IrcMessage,
@@ -104,9 +113,9 @@ class _MsgParseExpectation:
         def divide_msg(msg: IrcMessage) -> Optional[tuple[StrTuplable, ...]]:
             from_msg: list[StrTuplable] = []
             idx_after_list = 0
-            for idx, param in enumerate(self.params):
+            for idx, param in enumerate(self._params):
                 if param.type_ == _MsgToken.LIST:
-                    remaining_exp_params = len(self.params) - idx
+                    remaining_exp_params = len(self._params) - idx
                     idx_after_list = len(msg.params) - remaining_exp_params + 1
                     from_msg += [' '.join(msg.params[idx:idx_after_list])]
                     from_msg += list(msg.params[idx_after_list:])
@@ -114,12 +123,11 @@ class _MsgParseExpectation:
                 from_msg += msg.params[idx:idx + 1]  # collect [] if none there
             if len(from_msg) < len(msg.params) and not idx_after_list:
                 return None  # not all msg.params collected
-            if len(self.params) != len(from_msg):
+            if len(self._params) != len(from_msg):
                 return None  # msg.params are too few or too many
             return tuple([msg.source] + from_msg)
 
-        def harvest_msg(exp_fields: tuple[_TokenExpectation, ...],
-                        msg_fields: tuple[StrTuplable, ...],
+        def harvest_msg(msg_fields: tuple[StrTuplable, ...],
                         validators: _MsgTokenValidatorDict
                         ) -> Optional[RetDict]:
             def parsed(type_: _MsgToken | str, to_parse: StrTuplable):
@@ -129,11 +137,11 @@ class _MsgParseExpectation:
             nickuserhosts: list[NickUserHost] = []
             for exp_tok, msg_tok in [(exp_tok, msg_fields[idx])
                                      for idx, exp_tok
-                                     in enumerate(exp_fields)]:
+                                     in enumerate(self._fields)]:
                 if not validators.get(exp_tok.type_, lambda _: True)(msg_tok):
-                    return None  # validator found for this type, failed it
+                    return None  # validator found for this type, but failed it
                 if isinstance(exp_tok.type_, str) and exp_tok.type_ != msg_tok:
-                    return None  # validator for "specific string"
+                    return None  # validator for specific string
                 if exp_tok.type_ is _MsgToken.NICK_USER_HOST\
                         and not exp_tok.code.skip_nuh:
                     nickuserhosts += [parsed(exp_tok.type_, msg_tok)]
@@ -142,14 +150,8 @@ class _MsgParseExpectation:
             return d | {'_nickuserhosts': tuple(nickuserhosts)}
 
         if (msg_fields := divide_msg(msg)):
-            exp_fields = tuple([self.source] + list(self.params))
-            if (to_ret := harvest_msg(exp_fields, msg_fields, validators)):
-                tasks: dict[_Command, list[str]] = {}
-                for code in (tuple(exp_field.code for exp_field in exp_fields)
-                             + self.bonus_tasks):
-                    for cmd in code.commands:
-                        tasks[cmd] = tasks.get(cmd, []) + [code.tok_name]
-                return to_ret | {'_verb': self.verb, '_tasks': tasks}
+            if (harvest := harvest_msg(msg_fields, validators)):
+                return harvest | self._harvest_invariables
         return None