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) | |