1 # SPDX-License-Identifier: GPL-2.0-only
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2023 by the Nominatim developer community.
 
   6 # For a full list of authors see the git log.
 
   8 Helper classes and functions for formatting results into API responses.
 
  10 from typing import Type, TypeVar, Dict, List, Callable, Any, Mapping
 
  11 from collections import defaultdict
 
  13 T = TypeVar('T') # pylint: disable=invalid-name
 
  14 FormatFunc = Callable[[T, Mapping[str, Any]], str]
 
  17 class FormatDispatcher:
 
  18     """ Helper class to conveniently create formatting functions in
 
  19         a module using decorators.
 
  22     def __init__(self) -> None:
 
  23         self.format_functions: Dict[Type[Any], Dict[str, FormatFunc[Any]]] = defaultdict(dict)
 
  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
 
  31         def decorator(func: FormatFunc[T]) -> FormatFunc[T]:
 
  32             self.format_functions[result_class][fmt] = func
 
  38     def list_formats(self, result_type: Type[Any]) -> List[str]:
 
  39         """ Return a list of formats supported by this formatter.
 
  41         return list(self.format_functions[result_type].keys())
 
  44     def supports_format(self, result_type: Type[Any], fmt: str) -> bool:
 
  45         """ Check if the given format is supported by this formatter.
 
  47         return fmt in self.format_functions[result_type]
 
  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.
 
  53             The format is expected to be in the list returned by
 
  56         return self.format_functions[type(result)][fmt](result, options)