diff --git a/cheuph/euphoria/config.py b/cheuph/euphoria/config.py index f00a7df..585fdd7 100644 --- a/cheuph/euphoria/config.py +++ b/cheuph/euphoria/config.py @@ -1,6 +1,6 @@ from typing import Any, Dict -__all__ = ["Config"] +__all__ = ["Fields", "Config", "ConfigView"] Fields = Dict[str, Any] @@ -86,3 +86,45 @@ class Config: self.fields.pop(key) else: self.fields[key] = value + + @property + def view(self) -> "ConfigView": + return ConfigView( + self.to_tree(self.default_fields), + self.to_tree(self.fields), + ) + +class ConfigView: + def __init__(self, + default_fields: Any, + fields: Any, + prefix: str = "", + ) -> None: + + self._default_fields = default_fields + self._fields = fields + self._prefix = prefix + + def __getattr__(self, name: str) -> Any: + """ + This function assumes that _default_fields and _fields have the same + dict structure. + """ + + default_field = self._default_fields.get(name) + field = self._fields.get(name) + + if isinstance(field, dict) or isinstance(default_field, dict): + # At least one is a dict, the other is either also a dict of the + # same structure or None. + default_field = default_field or {} + field = field or {} + + return ConfigView(default_field, field, f"{self._prefix}{name}.") + + value = default_field if field is None else field + + if value is None: + raise ConfigException(f"Field {self._prefix}{name} does not exist") + + return value