2021-01-24 19:53:51 +00:00
|
|
|
from abc import ABC, abstractmethod
|
2021-01-24 20:58:02 +00:00
|
|
|
from functools import reduce
|
|
|
|
from operator import or_
|
2021-01-24 21:03:53 +00:00
|
|
|
import re
|
2021-01-24 19:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ValidatorException(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class Validator(ABC):
|
|
|
|
@staticmethod
|
|
|
|
def of(x):
|
|
|
|
if isinstance(x, Validator):
|
|
|
|
return x
|
|
|
|
if callable(x):
|
|
|
|
return LambdaValidator(x)
|
2021-01-24 20:25:26 +00:00
|
|
|
if x in validator_types:
|
|
|
|
return validator_types[x]()
|
2021-01-24 19:53:51 +00:00
|
|
|
raise ValidatorException("Cannot create validator")
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def isValid(self, value):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class LambdaValidator(Validator):
|
|
|
|
def __init__(self, c):
|
|
|
|
self.callable = c
|
|
|
|
|
|
|
|
def isValid(self, value):
|
|
|
|
return self.callable(value)
|
|
|
|
|
|
|
|
|
2021-01-24 20:58:02 +00:00
|
|
|
class TypeValidator(Validator):
|
|
|
|
def __init__(self, type):
|
|
|
|
self.type = type
|
|
|
|
super().__init__()
|
|
|
|
|
2021-01-24 19:53:51 +00:00
|
|
|
def isValid(self, value):
|
2021-01-24 20:58:02 +00:00
|
|
|
return isinstance(value, self.type)
|
2021-01-24 19:53:51 +00:00
|
|
|
|
|
|
|
|
2021-01-24 20:58:02 +00:00
|
|
|
class IntegerValidator(TypeValidator):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(int)
|
|
|
|
|
|
|
|
|
|
|
|
class FloatValidator(TypeValidator):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(float)
|
|
|
|
|
|
|
|
|
|
|
|
class StringValidator(TypeValidator):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(str)
|
2021-01-24 19:53:51 +00:00
|
|
|
|
|
|
|
|
2021-01-24 20:58:02 +00:00
|
|
|
class BoolValidator(TypeValidator):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(bool)
|
|
|
|
|
|
|
|
|
|
|
|
class OrValidator(Validator):
|
|
|
|
def __init__(self, *validators):
|
|
|
|
self.validators = validators
|
|
|
|
super().__init__()
|
|
|
|
|
2021-01-24 19:53:51 +00:00
|
|
|
def isValid(self, value):
|
2021-01-24 20:58:02 +00:00
|
|
|
return reduce(
|
|
|
|
or_,
|
|
|
|
[v.isValid(value) for v in self.validators],
|
|
|
|
False
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
class NumberValidator(OrValidator):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(IntegerValidator(), FloatValidator())
|
2021-01-24 20:25:26 +00:00
|
|
|
|
|
|
|
|
2021-01-24 21:28:48 +00:00
|
|
|
class RegexValidator(StringValidator):
|
2021-01-24 21:03:53 +00:00
|
|
|
def __init__(self, regex: re.Pattern):
|
|
|
|
self.regex = regex
|
2021-01-24 21:28:48 +00:00
|
|
|
super().__init__()
|
2021-01-24 21:03:53 +00:00
|
|
|
|
|
|
|
def isValid(self, value):
|
2021-01-24 21:28:48 +00:00
|
|
|
return super().isValid(value) and self.regex.match(value) is not None
|
2021-01-24 21:03:53 +00:00
|
|
|
|
|
|
|
|
2021-01-24 20:25:26 +00:00
|
|
|
validator_types = {
|
|
|
|
"string": StringValidator,
|
|
|
|
"str": StringValidator,
|
|
|
|
"integer": IntegerValidator,
|
|
|
|
"int": IntegerValidator,
|
|
|
|
"number": NumberValidator,
|
|
|
|
"num": NumberValidator,
|
|
|
|
}
|