Source code for easydata.parsers.clause

from typing import Any, Callable, Optional

from easydata.parsers.base import Base
from easydata.typing import Parser
from easydata.utils import mix, parse

__all__ = (
    "OR",
    "WITH",
    "SWITCH",
    "IF",
)


[docs]class OR(Base): _min_len_error_msg = "At least two parsers needs to be passed in order " "to use {}" def __init__( self, *args, strict_none: bool = False, ): self.parsers = args self._strict_none = strict_none self._validate_fields() def parse( self, data: Any, parent_data: Any = None, with_parent_data: bool = False, ) -> Any: for parser in self.parsers: value = parse.value_from_parser( parser=parser, data=data, parent_data=parent_data, with_parent_data=with_parent_data, config=self.config, ) if self._strict_none and value is not None: return value elif not self._strict_none and value: return value def _validate_fields(self): if len(self.parsers) == 1: cls_name = self.__class__.__name__ raise ValueError(self._min_len_error_msg.format(cls_name))
[docs]class WITH(OR): def parse( self, data: Any, parent_data: Any = None, with_parent_data: bool = False, ) -> Any: parsers = list(self.parsers) value = ( parsers.pop(0) .init_config(self.config) .parse( data=data, parent_data=parent_data, with_parent_data=with_parent_data, ) ) for parser in parsers: value = parser.init_config(self.config).parse(value) return value
[docs]class SWITCH(Base): def __init__( self, parser: Parser, *cases, default: Any = None, ): self._parser = parser self._cases = cases self._default = default def parse( self, data: Any, parent_data: Any = None, with_parent_data: bool = False, ) -> Any: parser_data = { "data": data, "parent_data": parent_data, "with_parent_data": with_parent_data, "config": self.config, } value = parse.value_from_parser( parser=self._parser, **parser_data, ) for case in self._cases: if not isinstance(case, tuple): raise TypeError( "Case must be of type tuple (<case-value>, <return-parser>)", ) case_value, return_parser = case if case_value == value: if mix.is_built_in_type(return_parser): return return_parser return parse.value_from_parser( parser=return_parser, **parser_data, ) if self._default: if mix.is_built_in_type(self._default): return self._default return parse.value_from_parser( parser=self._default, **parser_data, ) return None
[docs]class IF(Base): def __init__( self, if_parser: Parser, then_parser: Any, else_parser: Optional[Any] = None, condition: Optional[Callable] = None, ): self._if_parser = if_parser self._then_parser = then_parser self._else_parser = else_parser self._condition = condition def parse( self, data: Any, parent_data: Any = None, with_parent_data: bool = False, ) -> Any: parser_data = { "data": data, "parent_data": parent_data, "with_parent_data": with_parent_data, "config": self.config, } condition_value = parse.value_from_parser( parser=self._if_parser, **parser_data, ) if self._has_condition(condition_value): if mix.is_built_in_type(self._then_parser): return self._then_parser value = parse.value_from_parser( parser=self._then_parser, **parser_data, ) return value if self._else_parser: if mix.is_built_in_type(self._else_parser): return self._else_parser return parse.value_from_parser( parser=self._else_parser, **parser_data, ) return None def _has_condition(self, value): if self._condition: return self._condition(value) return value