feat: Infrastructure for automatic control widget creation for configuration fields
Change-Id: I87a0eb6ba5b2128c779f04c8971106b1c8fbd33f
diff --git a/dcs/config/ui/ui_create.py b/dcs/config/ui/ui_create.py
new file mode 100644
index 0000000..1bff499
--- /dev/null
+++ b/dcs/config/ui/ui_create.py
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+from __future__ import annotations
+
+from typing import Type, List, Dict, Optional
+from pydantic import BaseModel
+
+from .base import ConfigWidget
+
+
+_CLASS_REGISTRY: List[Type[ConfigWidget]] = [
+]
+
+
+def _find_widget_classes(tp: Type, is_list: bool = False) -> Dict[Optional[str], Type[ConfigWidget]]:
+ widget_classes: Dict[Optional[str], Type[ConfigWidget]] = {}
+ if is_list:
+ raise NotImplementedError
+ else:
+ for cls in _CLASS_REGISTRY:
+ if issubclass(tp, cls.MODEL_TYPE):
+ widget_classes[cls.FLAVOUR] = cls
+ if len(widget_classes) == 0:
+ raise TypeError(f'No widget class for {repr(tp)} found.')
+ return widget_classes
+
+
+def _add_ui_create(model_cls: BaseModel, tp: Type[int], name: str, widget_type: Type[ConfigWidget],
+ flavour: Optional[str]):
+ suffix = f'_{flavour}' if flavour is not None else ''
+ setattr(model_cls, f'ui_create_{name}{suffix}', widget_type.make_ui_create_method(tp, name))
+
+
+def ui_create(cls: BaseModel):
+ for field in cls.__fields__.values():
+ name = field.name
+ tp = field.type_
+ is_list = isinstance(field.default, list)
+ try:
+ widget_classes = _find_widget_classes(tp, is_list)
+ for flavour, wgd_cls in widget_classes.items():
+ _add_ui_create(cls, tp, name, wgd_cls, flavour)
+ except TypeError as e:
+ print(e)
+ return cls