|
| 1 | +from typing import ( |
| 2 | + TYPE_CHECKING, |
| 3 | + Dict, |
| 4 | + Text, |
| 5 | + Optional, |
| 6 | + Union, |
| 7 | + Type |
| 8 | +) |
| 9 | +import pkg_resources |
| 10 | + |
| 11 | +if TYPE_CHECKING: |
| 12 | + from sifter.grammar.rule import Rule |
| 13 | + from sifter.grammar.comparator import Comparator |
| 14 | + |
| 15 | + |
| 16 | +class ExtensionRegistry(): |
| 17 | + |
| 18 | + _HANDLERS_MAP: Dict[Text, Dict[Text, Union[bool, Type['Comparator'], Type['Rule']]]] = {} |
| 19 | + DEFAULT_EXTENSION = [ |
| 20 | + 'regex', |
| 21 | + 'comparator-i;ascii-casemap', |
| 22 | + 'comparator-i;octet', |
| 23 | + 'fileinto', |
| 24 | + ] |
| 25 | + |
| 26 | + def __init__(self) -> None: |
| 27 | + for extension_name in self.DEFAULT_EXTENSION: |
| 28 | + self.register_extension(extension_name) |
| 29 | + |
| 30 | + for entry_point in pkg_resources.iter_entry_points('sifter_extensions'): |
| 31 | + self.register_handler(entry_point.load()) |
| 32 | + |
| 33 | + @classmethod |
| 34 | + def register_extension(cls, extension_name): |
| 35 | + cls.register('extension', extension_name, True) |
| 36 | + |
| 37 | + @classmethod |
| 38 | + def register_handler(cls, ext_cls): |
| 39 | + cls.register(ext_cls.handler_type(), ext_cls.handler_id(), ext_cls) |
| 40 | + |
| 41 | + @classmethod |
| 42 | + def register( |
| 43 | + cls, |
| 44 | + handler_type: Optional[Text], |
| 45 | + handler_id: Optional[Text], |
| 46 | + value: Union[bool, Type['Comparator'], Type['Rule']] |
| 47 | + ) -> None: |
| 48 | + cls._HANDLERS_MAP.setdefault(handler_type, {})[handler_id] = value |
| 49 | + |
| 50 | + @classmethod |
| 51 | + def unregister(cls, handler_type: Text, handler_id: Text) -> Optional[Union[bool, Type['Comparator'], Type['Rule']]]: |
| 52 | + return cls._HANDLERS_MAP.get(handler_type, {}).pop(handler_id, None) |
| 53 | + |
| 54 | + @classmethod |
| 55 | + def get(cls, handler_type: Text, handler_id: Text) -> Optional[Union[bool, Type['Comparator'], Type['Rule']]]: |
| 56 | + return cls._HANDLERS_MAP.get(handler_type, {}).get(handler_id, None) |
0 commit comments