54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
from typing import List
|
|
from typing import Set
|
|
|
|
from ytdl_subscribe.validators.validators import DictValidator
|
|
|
|
|
|
class StrictDictValidator(DictValidator):
|
|
"""
|
|
Validates dictionary-based fields with required and optional keys.
|
|
"""
|
|
|
|
_required_keys: Set[str] = set()
|
|
_optional_keys: Set[str] = set()
|
|
_allow_extra_keys = False
|
|
|
|
def __init__(self, name, value):
|
|
super().__init__(name, value)
|
|
|
|
if len(self._allowed_keys) == 0:
|
|
raise ValueError(
|
|
"No required or optional keys defined when using a StrictDictValidator. "
|
|
"Should be using DictValidator instead."
|
|
)
|
|
|
|
# Ensure all required keys are present
|
|
for required_key in self._required_keys:
|
|
if required_key not in self._dict:
|
|
raise self._validation_exception(f"missing the required field '{required_key}'")
|
|
|
|
# Ensure an empty dict was not passed as the value
|
|
if not self._dict:
|
|
raise self._validation_exception(
|
|
f"at least one of the following fields must be defined: "
|
|
f"{', '.join(self._optional_keys)}'"
|
|
)
|
|
|
|
# Ensure all keys are either required or optional keys if no extra field are allowed
|
|
if not self._allow_extra_keys:
|
|
for object_key in self._keys:
|
|
if object_key not in self._allowed_keys:
|
|
error_msg = (
|
|
f"'{self._name}' contains the field '{object_key}' which is not allowed. "
|
|
f"Allowed fields: {', '.join(self._allowed_keys)}"
|
|
)
|
|
raise self._validation_exception(str(error_msg))
|
|
|
|
@property
|
|
def _allowed_keys(self) -> List[str]:
|
|
"""
|
|
Returns
|
|
-------
|
|
Sorted list of required and optional keys
|
|
"""
|
|
return sorted(list(self._required_keys.union(self._optional_keys)))
|