Spaces:
Sleeping
Sleeping
| import re | |
| from functools import wraps | |
| from itertools import islice | |
| from typing import Callable, Union, Pattern | |
| from .base import Loader, ILoaderClass | |
| STRING_PROCESSOR = Callable[[str], str] | |
| def enum(*items, case_sensitive: bool = True) -> ILoaderClass: | |
| """ | |
| Overview: | |
| Create an enum loader. | |
| Arguments: | |
| - items (:obj:`Iterable[str]`): The items. | |
| - case_sensitive (:obj:`bool`): Whether case sensitive. | |
| """ | |
| def _case_sensitive(func: STRING_PROCESSOR) -> STRING_PROCESSOR: | |
| if case_sensitive: | |
| return func | |
| else: | |
| def _new_func(value: str) -> str: | |
| return func(value).lower() | |
| return _new_func | |
| def _item_process(value): | |
| return str(value) | |
| item_set = set([_item_process(item) for item in items]) | |
| def _load(value: str): | |
| real_value = _item_process(value) | |
| if real_value not in item_set: | |
| raise ValueError('unknown enum value {value}'.format(value=repr(value))) | |
| return real_value | |
| return Loader(_load) | |
| def _to_regexp(regexp) -> Pattern: | |
| """ | |
| Overview: | |
| Convert regexp to re.Pattern. | |
| Arguments: | |
| - regexp (:obj:`Union[str, re.Pattern]`): The regexp. | |
| """ | |
| if isinstance(regexp, Pattern): | |
| return regexp | |
| elif isinstance(regexp, str): | |
| return re.compile(regexp) | |
| else: | |
| raise TypeError( | |
| 'Regexp should be either str or re.Pattern but {actual} found.'.format(actual=repr(type(regexp).__name__)) | |
| ) | |
| def rematch(regexp: Union[str, Pattern]) -> ILoaderClass: | |
| """ | |
| Overview: | |
| Create a rematch loader. | |
| Arguments: | |
| - regexp (:obj:`Union[str, re.Pattern]`): The regexp. | |
| """ | |
| regexp = _to_regexp(regexp) | |
| def _load(value: str): | |
| if not regexp.fullmatch(value): | |
| raise ValueError( | |
| 'fully match with regexp {pattern} expected but {actual} found'.format( | |
| pattern=repr(regexp.pattern), | |
| actual=repr(value), | |
| ) | |
| ) | |
| return value | |
| return Loader(_load) | |
| def regrep(regexp: Union[str, Pattern], group: int = 0) -> ILoaderClass: | |
| """ | |
| Overview: | |
| Create a regrep loader. | |
| Arguments: | |
| - regexp (:obj:`Union[str, re.Pattern]`): The regexp. | |
| - group (:obj:`int`): The group. | |
| """ | |
| regexp = _to_regexp(regexp) | |
| def _load(value: str): | |
| results = list(islice(regexp.finditer(value), 1)) | |
| if results: | |
| return results[0][group] | |
| else: | |
| raise ValueError( | |
| 'fully match with regexp {pattern} expected but {actual} found'.format( | |
| pattern=repr(regexp.pattern), | |
| actual=repr(value), | |
| ) | |
| ) | |
| return Loader(_load) | |