from ..Exceptions.CLI.Validators import ValidationError
from typing import cast, TypeVar, Generic
from abc import ABC, abstractmethod
from datetime import datetime
from pathlib import Path
from enum import Enum
import dateparser
import validators
#==========================================================================================#
# >>>>> БАЗОВЫЙ КЛАСС <<<<< #
#==========================================================================================#
_PARSED_VALUE = TypeVar("_PARSED_VALUE")
[документация]
class BaseValidator(ABC, Generic[_PARSED_VALUE]):
"""Базовый валидатор строки."""
[документация]
@staticmethod
@abstractmethod
def convert(value: str) -> _PARSED_VALUE:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: Any
"""
pass
[документация]
@classmethod
def parse(cls, value: str) -> _PARSED_VALUE:
"""
Проводит валидацию строки и преобразует её в целевой тип.
:param value: Обрабатываемая строка.
:type value: str
:return: Результат преобразования.
:rtype: Any
"""
if not cls.validate(value): raise ValidationError(value, cls)
return cls.convert(value)
[документация]
@staticmethod
@abstractmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
pass
#==========================================================================================#
# >>>>> ВАЛИДАТОРЫ <<<<< #
#==========================================================================================#
[документация]
class Validator_All(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
return True
[документация]
class Validator_Alpha(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
return value.isalpha()
[документация]
class Validator_Base64(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Result = validators.base64(value)
if type(Result) == bool: return Result
except validators.ValidationError: pass
return False
[документация]
class Validator_Bool(BaseValidator[bool]):
[документация]
@staticmethod
def convert(value: str) -> bool:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: bool
"""
value = value.lower()
if value in ("true",): return True
return False
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
Buffer = value.lower()
return Buffer in ("true", "false")
[документация]
class Validator_Datetime(BaseValidator[datetime]):
[документация]
@staticmethod
def convert(value: str) -> datetime:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: datetime
"""
return cast(datetime, dateparser.parse(value))
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
dateparser.parse(value)
return True
except: pass
return False
[документация]
class Validator_Email(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Result = validators.email(value)
if type(Result) == bool: return Result
except validators.ValidationError: pass
return False
[документация]
class Validator_Float(BaseValidator[float]):
[документация]
@staticmethod
def convert(value: str) -> float:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: float
"""
return float(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
return value.count("-") <= 1 and value.count(".") == 1 and value.replace(".", "").lstrip("-").isdigit()
[документация]
class Validator_Integer(BaseValidator[int]):
[документация]
@staticmethod
def convert(value: str) -> int:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: int
"""
return int(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
return value.count("-") <= 1 and value.lstrip("-").isdigit()
[документация]
class Validator_IPv4(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Result = validators.ipv4(value)
if type(Result) == bool: return Result
except validators.ValidationError: pass
return False
[документация]
class Validator_IPv6(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Result = validators.ipv6(value)
if type(Result) == bool: return Result
except validators.ValidationError: pass
return False
[документация]
class Validator_Number(BaseValidator[float | int]):
[документация]
@staticmethod
def convert(value: str) -> float | int:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: float | int
"""
return float(value) if "." in value else int(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
if "." in value:
try:
float(value)
return True
except ValueError: return False
else:
try:
int(value)
return True
except ValueError: return False
[документация]
class Validator_Path(BaseValidator[Path]):
[документация]
@staticmethod
def convert(value: str) -> Path:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: Path
"""
return Path(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Path(value)
return True
except: return False
[документация]
class Validator_UnsignedInteger(BaseValidator[int]):
[документация]
@staticmethod
def convert(value: str) -> int:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: int
"""
return int(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
return value.isdigit()
[документация]
class Validator_URL(BaseValidator[str]):
[документация]
@staticmethod
def convert(value: str) -> str:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: str
"""
return value
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try:
Result = validators.url(value)
if type(Result) == bool: return Result
except validators.ValidationError: pass
return False
[документация]
class Validator_ValidPath(BaseValidator[Path]):
[документация]
@staticmethod
def convert(value: str) -> Path:
"""
Конвертирует строку в значение определённого типа.
:param value: Конвертируемая строка.
:type value: str
:return: Конвертированное значение.
:rtype: Path
"""
return Path(value)
[документация]
@staticmethod
def validate(value: str) -> bool:
"""
Проверяет, соответствует ли строка критериям валидируемого типа.
:param value: Проверяемая строка.
:type value: str
:return: Возвращает `True`, если строка является валидным значением типа.
:rtype: bool
"""
try: return Path(value).exists()
except: return False
#==========================================================================================#
# >>>>> ПЕРЕЧИСЛЕНИЕ ВАЛИДАТОРОВ <<<<< #
#==========================================================================================#
[документация]
class ValidableTypes(Enum):
"""Перечисление типов валидаторов."""
All = Validator_All
Alpha = Validator_Alpha
Base64 = Validator_Base64
Bool = Validator_Bool
Datetime = Validator_Datetime
Email = Validator_Email
Float = Validator_Float
Integer = Validator_Integer
IPv4 = Validator_IPv4
IPv6 = Validator_IPv6
Number = Validator_Number
Path = Validator_Path
UnsignedInteger = Validator_UnsignedInteger
URL = Validator_URL
ValidPath = Validator_ValidPath