46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
from typing import Callable, Dict, List, NamedTuple, Optional, Tuple
|
|
|
|
from ics.grammar.parse import ContentLine
|
|
|
|
|
|
class ParserOption(NamedTuple):
|
|
required: bool = False
|
|
multiple: bool = False
|
|
default: Optional[List[ContentLine]] = None
|
|
|
|
|
|
class Parser:
|
|
@classmethod
|
|
def get_parsers(cls) -> Dict[str, Tuple[Callable, ParserOption]]:
|
|
methods = [
|
|
(method_name, getattr(cls, method_name))
|
|
for method_name in dir(cls)
|
|
if callable(getattr(cls, method_name))
|
|
]
|
|
parsers = [
|
|
(method_name, method_callable)
|
|
for (method_name, method_callable) in methods
|
|
if method_name.startswith("parse_")
|
|
]
|
|
return {
|
|
method_name.split("_", 1)[1]
|
|
.upper()
|
|
.replace("_", "-"): (
|
|
method_callable,
|
|
getattr(method_callable, "options", ParserOption()),
|
|
)
|
|
for (method_name, method_callable) in parsers
|
|
}
|
|
|
|
|
|
def option(
|
|
required: bool = False,
|
|
multiple: bool = False,
|
|
default: Optional[List[ContentLine]] = None,
|
|
) -> Callable:
|
|
def decorator(fn):
|
|
fn.options = ParserOption(required, multiple, default)
|
|
return fn
|
|
|
|
return decorator
|