Source code for grave_settings.validation

# - * -coding: utf - 8 - * -
"""


@author: ☙ Ryan McConnell ❧
"""
from collections import defaultdict
from dataclasses import dataclass
from typing import Callable, MutableMapping, Type, Iterable

VALIDATION_FIX_SIGNATURE = Callable[[MutableMapping, str], bool]
VALIDATION_FUNCTION_SIGNATURE = Callable[[MutableMapping, str, ...], VALIDATION_FIX_SIGNATURE | None]


[docs]@dataclass(slots=True, frozen=True) class ValidationReport(object): settings: MutableMapping settings_key: str name: str description: str long_description: str fixes: list[VALIDATION_FIX_SIGNATURE] | None = None
[docs]class Validation: def __init__(self, key: str): self.settings_key = key
[docs] def validate(self, settings: MutableMapping, settings_key: str) -> ValidationReport | None: return None
[docs] def make_validation_report(self, *args): return ValidationReport(*args)
[docs]class ValidationCapsule(Validation): validate: VALIDATION_FUNCTION_SIGNATURE make_validation_report: Callable[..., ValidationReport] = ValidationReport
[docs]class NotNoneValidation(Validation):
[docs] def validate(self, settings: MutableMapping, settings_key: str) -> ValidationReport | None: if settings[settings_key] is None: return self.make_validation_report(settings, settings_key, 'NoneType Error', 'Parameter has a value of None', f'Parameter {settings_key} in settings object {settings} has a value of None')
[docs]class TypeCheckValidation(Validation): def __init__(self, key: str, _type: Type): super().__init__(key) self.check_type = _type
[docs] def validate(self, settings: MutableMapping, settings_key: str) -> ValidationReport | None: sot = type(settings[settings_key]) check_type = self.check_type if sot is not check_type: return ValidationReport(settings, settings_key, 'TypeError', f'Parameter is expected to be {check_type.__class__.__name__}', (f'Parameter {settings_key} of {settings} is expected to be of type {check_type}, ' 'but instead is of type {sot}'))
[docs]class SettingsValidator(object): def __init__(self, settings: MutableMapping): self.settings = settings self.validations: list[Validation] = []
[docs] def create_validation(self, name: str, validation_function: VALIDATION_FUNCTION_SIGNATURE, v_t: Type[Validation] = Validation): self.add_validation(v_t(name, validation_function))
[docs] def create_validations(self, validations: list[tuple[str, VALIDATION_FUNCTION_SIGNATURE]], v_t: Type[Validation] = Validation): self.add_validations(v_t(*x) for x in validations)
[docs] def add_validation(self, validation: Validation): self.validations.append(validation)
[docs] def add_validations(self, validations: Iterable[Validation]): self.validations.extend(validations)
[docs] def get_validation_issues(self) -> dict: issues = defaultdict(list) for validation in self.validations: settings_key = validation.settings_key if vr := validation.validate(self.settings, settings_key): issues[settings_key].append(vr) return issues