aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/service/_base.py
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-11-11 01:12:29 +0800
committerYuqian Yang <crupest@crupest.life>2025-01-03 23:41:03 +0800
commitadec0f35eea3b9d955e5631d5b8e54092022116d (patch)
tree0c13bf85cec332b02c7acd1d0edb42aa9da75a32 /tools/cru-py/cru/service/_base.py
parent7e9fdc36310d1bc63af4f4a0fc2f4963ae0154aa (diff)
downloadcrupest-adec0f35eea3b9d955e5631d5b8e54092022116d.tar.gz
crupest-adec0f35eea3b9d955e5631d5b8e54092022116d.tar.bz2
crupest-adec0f35eea3b9d955e5631d5b8e54092022116d.zip
HALF WORK: 2024.1.3
Diffstat (limited to 'tools/cru-py/cru/service/_base.py')
-rw-r--r--tools/cru-py/cru/service/_base.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/tools/cru-py/cru/service/_base.py b/tools/cru-py/cru/service/_base.py
index 7bb09ad..c84ab05 100644
--- a/tools/cru-py/cru/service/_base.py
+++ b/tools/cru-py/cru/service/_base.py
@@ -3,12 +3,19 @@ from __future__ import annotations
from argparse import ArgumentParser, Namespace
from abc import ABC, abstractmethod
from collections.abc import Iterable
+from typing import TypeVar, overload
from cru import CruIterator, CruInternalError
from cru.app import ApplicationPath, CruApplication
+_F = TypeVar("_F")
-class AppFeatureProvider(ABC):
+
+class InternalAppException(CruInternalError):
+ pass
+
+
+class AppFeatureProvider:
def __init__(self, name: str, /, app: AppBase | None = None):
super().__init__()
self._name = name
@@ -33,6 +40,8 @@ class AppFeatureProvider(ABC):
self._app_paths.append(p)
return p
+
+class AppCommandFeatureProvider(AppFeatureProvider, ABC):
@abstractmethod
def add_arg_parser(self, arg_parser: ArgumentParser) -> None: ...
@@ -71,3 +80,25 @@ class AppBase(CruApplication):
def add_app_feature(self, feature: AppFeatureProvider) -> None:
self._app_features.append(feature)
+
+ @overload
+ def get_feature(self, feature: str) -> AppFeatureProvider: ...
+
+ @overload
+ def get_feature(self, feature: type[_F]) -> _F: ...
+
+ def get_feature(self, feature: str | type[_F]) -> AppFeatureProvider | _F:
+ if isinstance(feature, str):
+ for f in self._app_features:
+ if f.name == feature:
+ return f
+ elif isinstance(feature, type):
+ for f in self._app_features:
+ if isinstance(f, feature):
+ return f
+ else:
+ raise InternalAppException(
+ "Argument must be the name of feature or its class."
+ )
+
+ raise InternalAppException(f"Feature {feature} not found.")