]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/api/result_formatting.py
a6bfa91c64fb5befb8fdb4dcb4b8acd0cbbb7eb3
[nominatim.git] / nominatim / api / result_formatting.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2023 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Helper classes and functions for formating results into API responses.
9 """
10 from typing import Type, TypeVar, Dict, List, Callable, Any, Mapping
11 from collections import defaultdict
12
13 T = TypeVar('T') # pylint: disable=invalid-name
14 FormatFunc = Callable[[T, Mapping[str, Any]], str]
15
16
17 class FormatDispatcher:
18     """ Helper class to conveniently create formatting functions in
19         a module using decorators.
20     """
21
22     def __init__(self) -> None:
23         self.format_functions: Dict[Type[Any], Dict[str, FormatFunc[Any]]] = defaultdict(dict)
24
25
26     def format_func(self, result_class: Type[T],
27                     fmt: str) -> Callable[[FormatFunc[T]], FormatFunc[T]]:
28         """ Decorator for a function that formats a given type of result into the
29             selected format.
30         """
31         def decorator(func: FormatFunc[T]) -> FormatFunc[T]:
32             self.format_functions[result_class][fmt] = func
33             return func
34
35         return decorator
36
37
38     def list_formats(self, result_type: Type[Any]) -> List[str]:
39         """ Return a list of formats supported by this formatter.
40         """
41         return list(self.format_functions[result_type].keys())
42
43
44     def supports_format(self, result_type: Type[Any], fmt: str) -> bool:
45         """ Check if the given format is supported by this formatter.
46         """
47         return fmt in self.format_functions[result_type]
48
49
50     def format_result(self, result: Any, fmt: str, options: Mapping[str, Any]) -> str:
51         """ Convert the given result into a string using the given format.
52
53             The format is expected to be in the list returned by
54             `list_formats()`.
55         """
56         return self.format_functions[type(result)][fmt](result, options)