Move matchers to type package

This commit is contained in:
Bartłomiej Pluta
2019-07-09 22:53:10 +02:00
parent fe19ecc090
commit 1449eee363
32 changed files with 164 additions and 138 deletions

View File

@@ -1,39 +1,5 @@
# from smnp.type.model import Type
#
from smnp.type.model import Type
class Matcher:
def __init__(self, objectType, matcher, string):
self.type = objectType
self.matcher = matcher
self.string = string
def match(self, value):
if self.type is not None and self.type != value.type:
return False
return self.matcher(value)
def andWith(self, matcher):
if self.type != matcher.type:
raise RuntimeError("Support types of matches are not the same")
string = f"[{self.string} and {matcher.string}]"
return Matcher(self.type, lambda x: self.match(x) and matcher.match(x), string)
def orWith(self, matcher):
string = f"[{self.string} or {matcher.string}]"
return Matcher(None, lambda x: self.match(x) or matcher.match(x), string)
def __eq__(self, other):
return self.type == other.type and self.string == other.string
def __str__(self):
return self.string
def __repr__(self):
return self.__str__()
class Signature:
@@ -65,7 +31,7 @@ def varargSignature(varargMatcher, *basicSignature):
def doesNotMatchVararg(basicSignature):
return (False, *[None for n in basicSignature], None)
#
def signature(*signature):
@@ -88,65 +54,3 @@ def doesNotMatch(sign):
return (False, *[None for n in sign])
def allTypes():
allowedTypes = [t for t in Type if t != Type.VOID]
return ofTypes(*allowedTypes)
def ofTypes(*types):
def check(value):
return value.type in types
return Matcher(None, check, f"<{', '.join([t.name.lower() for t in types])}>")
def ofType(type):
def check(value):
return value.type == type
return Matcher(None, check, type.name.lower())
def listOf(*types):
def check(value):
return len([item for item in value.value if not item.type in types]) == 0
return Matcher(Type.LIST, check, f"{Type.LIST.name.lower()}<{', '.join([t.name.lower() for t in types])}>")
def listOfMatchers(*matchers):
def check(value):
matched = 0
for item in value.value:
matched += 1 if any(matcher.match(item) for matcher in matchers) else 0
return matched == len(value.value)
return Matcher(Type.LIST, check, f"{Type.LIST.name.lower()}<{', '.join([m.string for m in matchers])}>")
def mapOfMatchers(keyMatchers, valueMatchers):
def check(map):
matched = 0
for key, value in map.value.items():
matched += 1 if any(matcher.match(key) for matcher in keyMatchers) \
and any(matcher.match(value) for matcher in valueMatchers) else 0
return matched == len(map.value)
return Matcher(Type.MAP, check, f"{Type.MAP.name.lower()}<{', '.join([m.string for m in keyMatchers])}><{', '.join([m.string for m in valueMatchers])}>")
def listMatches(*pattern):
def check(value):
return signature(*pattern).check(value.value)[0]
return Matcher(Type.LIST, check, f"({', '.join([str(m) for m in pattern])})")
def recursiveListMatcher(matcher):
if matcher.type == Type.LIST:
raise RuntimeError(f"Passed matcher will be handling non-list types, so it cannot have type set to {Type.LIST}")
def check(value):
if value.type != Type.LIST:
return matcher.match(value)
for item in value.value:
return check(item)
return Matcher(Type.LIST, check, f"[LISTS OF {str(matcher)}]")