allow Formatless and Folded to be nested

This commit is contained in:
jesopo 2020-06-01 14:17:19 +01:00
parent 97c4a616c9
commit 5b04a5d1fd
2 changed files with 49 additions and 12 deletions

View file

@ -67,6 +67,11 @@ class IMatchResponse(object):
class IMatchResponseParam(object): class IMatchResponseParam(object):
def match(self, server: "IServer", arg: str) -> bool: def match(self, server: "IServer", arg: str) -> bool:
pass pass
class IMatchResponseValueParam(IMatchResponseParam):
def value(self, server: "IServer"):
pass
def set_value(self, value: str):
pass
class IMatchResponseHostmask(object): class IMatchResponseHostmask(object):
def match(self, server: "IServer", hostmask: Hostmask) -> bool: def match(self, server: "IServer", hostmask: Hostmask) -> bool:
pass pass

View file

@ -1,7 +1,8 @@
from re import compile as re_compile from re import compile as re_compile
from typing import Optional, Pattern from typing import Optional, Pattern, Union
from irctokens import Hostmask from irctokens import Hostmask
from ..interface import IMatchResponseParam, IMatchResponseHostmask, IServer from ..interface import (IMatchResponseParam, IMatchResponseValueParam,
IMatchResponseHostmask, IServer)
from ..glob import Glob, compile as glob_compile from ..glob import Glob, compile as glob_compile
from .. import formatting from .. import formatting
@ -12,14 +13,32 @@ class Any(IMatchResponseParam):
return True return True
ANY = Any() ANY = Any()
class Literal(IMatchResponseParam): # NOT
# FORMAT FOLD
# REGEX
# LITERAL
class Literal(IMatchResponseValueParam):
def __init__(self, value: str): def __init__(self, value: str):
self._value = value self._value = value
def __repr__(self) -> str: def __repr__(self) -> str:
return f"{self._value!r}" return f"{self._value!r}"
def value(self, server: IServer) -> str:
return self._value
def set_value(self, value: str):
self._value = value
def match(self, server: IServer, arg: str) -> bool: def match(self, server: IServer, arg: str) -> bool:
return arg == self._value return arg == self._value
TYPE_MAYBELIT = Union[str, IMatchResponseParam]
TYPE_MAYBELIT_VALUE = Union[str, IMatchResponseValueParam]
def _assure_lit(value: TYPE_MAYBELIT_VALUE) -> IMatchResponseValueParam:
if isinstance(value, str):
return Literal(value)
else:
return value
class Not(IMatchResponseParam): class Not(IMatchResponseParam):
def __init__(self, param: IMatchResponseParam): def __init__(self, param: IMatchResponseParam):
self._param = param self._param = param
@ -28,24 +47,37 @@ class Not(IMatchResponseParam):
def match(self, server: IServer, arg: str) -> bool: def match(self, server: IServer, arg: str) -> bool:
return not self._param.match(server, arg) return not self._param.match(server, arg)
class Folded(IMatchResponseParam): class ParamValuePassthrough(IMatchResponseValueParam):
def __init__(self, value: str): _value: IMatchResponseValueParam
self._value = value def value(self, server: IServer):
self._folded: Optional[str] = None return self._value.value(server)
def set_value(self, value: str):
self._value.set_value(value)
class Folded(ParamValuePassthrough):
def __init__(self, value: TYPE_MAYBELIT_VALUE):
self._value = _assure_lit(value)
self._folded = False
def __repr__(self) -> str: def __repr__(self) -> str:
return f"Folded({self._value!r})" return f"Folded({self._value!r})"
def match(self, server: IServer, arg: str) -> bool: def match(self, server: IServer, arg: str) -> bool:
if self._folded is None: if not self._folded:
self._folded = server.casefold(self._value) value = self.value(server)
return self._folded == server.casefold(arg) folded = server.casefold(value)
self.set_value(folded)
self._folded = True
class Formatless(Literal): return self._value.match(server, server.casefold(arg))
class Formatless(IMatchResponseParam):
def __init__(self, value: TYPE_MAYBELIT_VALUE):
self._value = _assure_lit(value)
def __repr__(self) -> str: def __repr__(self) -> str:
brepr = super().__repr__() brepr = super().__repr__()
return f"Formatless({brepr})" return f"Formatless({brepr})"
def match(self, server: IServer, arg: str) -> bool: def match(self, server: IServer, arg: str) -> bool:
strip = formatting.strip(arg) strip = formatting.strip(arg)
return super().match(server, strip) return self._value.match(server, strip)
class Regex(IMatchResponseParam): class Regex(IMatchResponseParam):
def __init__(self, value: str): def __init__(self, value: str):