aboutsummaryrefslogtreecommitdiff
path: root/tools/cru-py/cru/_func.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cru-py/cru/_func.py')
-rw-r--r--tools/cru-py/cru/_func.py262
1 files changed, 90 insertions, 172 deletions
diff --git a/tools/cru-py/cru/_func.py b/tools/cru-py/cru/_func.py
index ef3da72..1b437be 100644
--- a/tools/cru-py/cru/_func.py
+++ b/tools/cru-py/cru/_func.py
@@ -10,59 +10,77 @@ from typing import (
ParamSpec,
TypeAlias,
TypeVar,
- cast,
)
+
from ._cru import CRU
from ._const import CruPlaceholder
_P = ParamSpec("_P")
+_P1 = ParamSpec("_P1")
_T = TypeVar("_T")
-_ArgsChainableCallable: TypeAlias = Callable[..., Iterable[Any]]
-_KwargsChainableCallable: TypeAlias = Callable[..., Iterable[tuple[str, Any]]]
-_ChainableCallable: TypeAlias = Callable[
- ..., tuple[Iterable[Any], Iterable[tuple[str, Any]]]
-]
+class _Dec:
+ @staticmethod
+ def wrap(
+ origin: Callable[_P, Callable[_P1, _T]]
+ ) -> Callable[_P, _Wrapper[_P1, _T]]:
+ def _wrapped(*args: _P.args, **kwargs: _P.kwargs) -> _Wrapper[_P1, _T]:
+ return _Wrapper(origin(*args, **kwargs))
+ return _wrapped
-class CruFunctionMeta:
- class Base:
- @staticmethod
- def none(*_v, **_kwargs) -> None:
- return None
- @staticmethod
- def true(*_v, **_kwargs) -> Literal[True]:
- return True
+class _RawBase:
+ @staticmethod
+ def none(*_v, **_kwargs) -> None:
+ return None
- @staticmethod
- def false(*_v, **_kwargs) -> Literal[False]:
- return False
+ @staticmethod
+ def true(*_v, **_kwargs) -> Literal[True]:
+ return True
- @staticmethod
- def identity(v: _T) -> _T:
- return v
+ @staticmethod
+ def false(*_v, **_kwargs) -> Literal[False]:
+ return False
- @staticmethod
- def only_you(v: _T, *_v, **_kwargs) -> _T:
- return v
+ @staticmethod
+ def identity(v: _T) -> _T:
+ return v
- @staticmethod
- def equal(a: Any, b: Any) -> bool:
- return a == b
+ @staticmethod
+ def only_you(v: _T, *_v, **_kwargs) -> _T:
+ return v
- @staticmethod
- def not_equal(a: Any, b: Any) -> bool:
- return a != b
+ @staticmethod
+ def equal(a: Any, b: Any) -> bool:
+ return a == b
- @staticmethod
- def not_(v: Any) -> Any:
- return not v
+ @staticmethod
+ def not_equal(a: Any, b: Any) -> bool:
+ return a != b
@staticmethod
- def bind(func: Callable[..., _T], *bind_args, **bind_kwargs) -> Callable[..., _T]:
+ def not_(v: Any) -> Any:
+ return not v
+
+
+class _Wrapper(Generic[_P, _T]):
+ def __init__(self, f: Callable[_P, _T]):
+ self._f = f
+
+ @property
+ def me(self) -> Callable[_P, _T]:
+ return self._f
+
+ def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T:
+ return self._f(*args, **kwargs)
+
+ @_Dec.wrap
+ def bind(self, *bind_args, **bind_kwargs) -> Callable[..., _T]:
+ func = self.me
+
def bound_func(*args, **kwargs):
popped = 0
real_args = []
@@ -82,174 +100,74 @@ class CruFunctionMeta:
KWARGS = auto()
BOTH = ARGS | KWARGS
- ArgsChainableCallable = _ArgsChainableCallable
- KwargsChainableCallable = _KwargsChainableCallable
- ChainableCallable = _ChainableCallable
+ ArgsChainableCallable: TypeAlias = Callable[..., Iterable[Any]]
+ KwargsChainableCallable: TypeAlias = Callable[..., Iterable[tuple[str, Any]]]
+ ChainableCallable: TypeAlias = Callable[
+ ..., tuple[Iterable[Any], Iterable[tuple[str, Any]]]
+ ]
- @staticmethod
+ @_Dec.wrap
def chain_with_args(
- funcs: Iterable[_ArgsChainableCallable], *bind_args, **bind_kwargs
- ) -> _ArgsChainableCallable:
+ self, funcs: Iterable[ArgsChainableCallable], *bind_args, **bind_kwargs
+ ) -> ArgsChainableCallable:
def chained_func(*args):
+ args = self.bind(*bind_args, **bind_kwargs)(*args)
+
for func in funcs:
- args = CruFunctionMeta.bind(func, *bind_args, **bind_kwargs)(*args)
+ args = _Wrapper(func).bind(*bind_args, **bind_kwargs)(*args)
return args
return chained_func
- @staticmethod
+ @_Dec.wrap
def chain_with_kwargs(
- funcs: Iterable[_KwargsChainableCallable], *bind_args, **bind_kwargs
- ) -> _KwargsChainableCallable:
+ self, funcs: Iterable[KwargsChainableCallable], *bind_args, **bind_kwargs
+ ) -> KwargsChainableCallable:
def chained_func(**kwargs):
+ kwargs = self.bind(*bind_args, **bind_kwargs)(**kwargs)
for func in funcs:
- kwargs = CruFunctionMeta.bind(func, *bind_args, **bind_kwargs)(**kwargs)
+ kwargs = _Wrapper(func).bind(func, *bind_args, **bind_kwargs)(**kwargs)
return kwargs
return chained_func
- @staticmethod
+ @_Dec.wrap
def chain_with_both(
- funcs: Iterable[_ChainableCallable], *bind_args, **bind_kwargs
- ) -> _ChainableCallable:
+ self, funcs: Iterable[ChainableCallable], *bind_args, **bind_kwargs
+ ) -> ChainableCallable:
def chained_func(*args, **kwargs):
for func in funcs:
- args, kwargs = CruFunctionMeta.bind(func, *bind_args, **bind_kwargs)(
+ args, kwargs = _Wrapper(func).bind(func, *bind_args, **bind_kwargs)(
*args, **kwargs
)
return args, kwargs
return chained_func
- @staticmethod
- def chain(
- mode: ChainMode,
- funcs: Iterable[
- _ArgsChainableCallable | _KwargsChainableCallable | _ChainableCallable
- ],
- *bind_args,
- **bind_kwargs,
- ) -> _ArgsChainableCallable | _KwargsChainableCallable | _ChainableCallable:
- if mode == CruFunctionMeta.ChainMode.ARGS:
- return CruFunctionMeta.chain_with_args(
- cast(Iterable[_ArgsChainableCallable], funcs),
- *bind_args,
- **bind_kwargs,
- )
- elif mode == CruFunctionMeta.ChainMode.KWARGS:
- return CruFunctionMeta.chain_with_kwargs(
- cast(Iterable[_KwargsChainableCallable], funcs),
- *bind_args,
- **bind_kwargs,
- )
- elif mode == CruFunctionMeta.ChainMode.BOTH:
- return CruFunctionMeta.chain_with_both(
- cast(Iterable[_ChainableCallable], funcs), *bind_args, **bind_kwargs
- )
-
-
-class CruFunction(Generic[_P, _T]):
-
- def __init__(self, f: Callable[_P, _T]):
- self._f = f
-
- @property
- def me(self) -> Callable[_P, _T]:
- return self._f
- def bind(self, *bind_args, **bind_kwargs) -> CruFunction[..., _T]:
- return CruFunction(CruFunctionMeta.bind(self._f, *bind_args, **bind_kwargs))
+class _Base:
+ none = _Wrapper(_RawBase.none)
+ true = _Wrapper(_RawBase.true)
+ false = _Wrapper(_RawBase.false)
+ identity = _Wrapper(_RawBase.identity)
+ only_you = _Wrapper(_RawBase.only_you)
+ equal = _Wrapper(_RawBase.equal)
+ not_equal = _Wrapper(_RawBase.not_equal)
+ not_ = _Wrapper(_RawBase.not_)
- def _iter_with_self(
- self, funcs: Iterable[Callable[..., Any]]
- ) -> Iterable[Callable[..., Any]]:
- yield self
- yield from funcs
+class _Creators:
@staticmethod
- def chain_with_args(
- self,
- funcs: Iterable[_ArgsChainableCallable],
- *bind_args,
- **bind_kwargs,
- ) -> _ArgsChainableCallable:
- return CruFunction(
- CruFunctionMeta.chain_with_args(
- self._iter_with_self(funcs), *bind_args, **bind_kwargs
- )
- )
+ def make_isinstance_of_types(*types: type) -> Callable:
+ return _Wrapper(lambda v: type(v) in types)
- def chain_with_kwargs(
- self, funcs: Iterable[_KwargsChainableCallable], *bind_args, **bind_kwargs
- ) -> _KwargsChainableCallable:
- return CruFunction(
- CruFunctionMeta.chain_with_kwargs(
- self._iter_with_self(funcs), *bind_args, **bind_kwargs
- )
- )
- def chain_with_both(
- self, funcs: Iterable[_ChainableCallable], *bind_args, **bind_kwargs
- ) -> _ChainableCallable:
- return CruFunction(
- CruFunctionMeta.chain_with_both(
- self._iter_with_self(funcs), *bind_args, **bind_kwargs
- )
- )
-
- def chain(
- self,
- mode: CruFunctionChainMode,
- funcs: Iterable[
- _ArgsChainableCallable | _KwargsChainableCallable | _ChainableCallable
- ],
- *bind_args,
- **bind_kwargs,
- ) -> _ArgsChainableCallable | _KwargsChainableCallable | _ChainableCallable:
- return CruFunction(
- CruFunctionMeta.chain(
- mode, self._iter_with_self(funcs), *bind_args, **bind_kwargs
- )
- )
+class CruFunction:
+ RawBase = _RawBase
+ Base = _Base
+ Creators = _Creators
+ Wrapper = _Wrapper
+ Decorators = _Dec
- def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T:
- return self._f(*args, **kwargs)
- @staticmethod
- def make_chain(
- mode: CruFunctionChainMode,
- funcs: Iterable[
- _ArgsChainableCallable | _KwargsChainableCallable | _ChainableCallable
- ],
- *bind_args,
- **bind_kwargs,
- ) -> CruFunction:
- return CruFunction(
- CruFunctionMeta.chain(mode, funcs, *bind_args, **bind_kwargs)
- )
-
-
-class CruWrappedFunctions:
- none = CruFunction(CruRawFunctions.none)
- true = CruFunction(CruRawFunctions.true)
- false = CruFunction(CruRawFunctions.false)
- identity = CruFunction(CruRawFunctions.identity)
- only_you = CruFunction(CruRawFunctions.only_you)
- equal = CruFunction(CruRawFunctions.equal)
- not_equal = CruFunction(CruRawFunctions.not_equal)
- not_ = CruFunction(CruRawFunctions.not_)
-
-
-class CruFunctionGenerators:
- @staticmethod
- def make_isinstance_of_types(*types: type) -> Callable:
- return CruFunction(lambda v: type(v) in types)
-
-
-CRU.add_objects(
- CruRawFunctions,
- CruFunctionMeta,
- CruFunction,
- CruWrappedFunctions,
- CruFunctionGenerators,
-)
+CRU.add_objects(CruFunction)