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,
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:])
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):
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)]
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