]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/result_formatter/base.py
88f4d9183a3ff172fbe856741d88423d65312c2f
[nominatim.git] / nominatim / result_formatter / base.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2022 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Helper classes and function for writing result formatting modules.
9 """
10 from typing import Type, TypeVar, Dict, Mapping, List, Callable, Generic, Any
11 from collections import defaultdict
12
13 T = TypeVar('T') # pylint: disable=invalid-name
14 FormatFunc = Callable[[T], str]
15
16 class ResultFormatter(Generic[T]):
17     """ This class dispatches format calls to the appropriate formatting
18         function previously defined with the `format_func` decorator.
19     """
20
21     def __init__(self, funcs: Mapping[str, FormatFunc[T]]) -> None:
22         self.functions = funcs
23
24
25     def list_formats(self) -> List[str]:
26         """ Return a list of formats supported by this formatter.
27         """
28         return list(self.functions.keys())
29
30
31     def format(self, result: T, fmt: str) -> str:
32         """ Convert the given result into a string using the given format.
33
34             The format is expected to be in the list returned by
35             `list_formats()`.
36         """
37         return self.functions[fmt](result)
38
39
40 class FormatDispatcher:
41     """ A factory class for result formatters.
42     """
43
44     def __init__(self) -> None:
45         self.format_functions: Dict[Type[Any], Dict[str, FormatFunc[Any]]] = defaultdict(dict)
46
47
48     def format_func(self, result_class: Type[T],
49                     fmt: str) -> Callable[[FormatFunc[T]], FormatFunc[T]]:
50         """ Decorator for a function that formats a given type of result into the
51             selected format.
52         """
53         def decorator(func: FormatFunc[T]) -> FormatFunc[T]:
54             self.format_functions[result_class][fmt] = func
55             return func
56
57         return decorator
58
59
60     def __call__(self, result_class: Type[T]) -> ResultFormatter[T]:
61         """ Create an instance of a format class for the given result type.
62         """
63         return ResultFormatter(self.format_functions[result_class])