diff options
Diffstat (limited to 'tools/cru-py/cru/util/_func.py')
| -rw-r--r-- | tools/cru-py/cru/util/_func.py | 122 | 
1 files changed, 55 insertions, 67 deletions
| diff --git a/tools/cru-py/cru/util/_func.py b/tools/cru-py/cru/util/_func.py index 3221c94..d9f8044 100644 --- a/tools/cru-py/cru/util/_func.py +++ b/tools/cru-py/cru/util/_func.py @@ -1,16 +1,14 @@  from collections.abc import Callable -from typing import TypeVar, Any, ParamSpec +from typing import TypeVar +from ._cru import CRU  from ._const import CRU_PLACEHOLDER  T = TypeVar("T") -R = TypeVar("R") -R1 = TypeVar("R1") -P = ParamSpec("P") -P1 = ParamSpec("P1") +_PLACEHOLDER = CRU_PLACEHOLDER -class RawFunctions: +class CruRawFunctions:      @staticmethod      def none(*_v, **_kwargs) -> None:          return None @@ -28,15 +26,15 @@ class RawFunctions:          return v      @staticmethod -    def only_you(r: T, *_v, **_kwargs) -> T: -        return r +    def only_you(v: T, *_v, **_kwargs) -> T: +        return v      @staticmethod -    def equal(a: Any, b: Any) -> bool: +    def equal(a, b) -> bool:          return a == b      @staticmethod -    def not_equal(a: Any, b: Any) -> bool: +    def not_equal(a, b) -> bool:          return a != b      @staticmethod @@ -44,95 +42,85 @@ class RawFunctions:          return not v -class MetaFunction: +class CruFunctionMeta:      @staticmethod -    def bind(f: Callable[P, R], *bind_args, **bind_kwargs) -> Callable[P1, R1]: -        def bound(*args, **kwargs): +    def bind(func: Callable, *bind_args, **bind_kwargs) -> Callable: +        def bound_func(*args, **kwargs):              popped = 0              real_args = [] -            for a in bind_args: -                if a is CRU_PLACEHOLDER: +            for arg in bind_args: +                if arg is _PLACEHOLDER:                      real_args.append(args[popped])                      popped += 1                  else: -                    real_args.append(a) +                    real_args.append(arg)              real_args.extend(args[popped:]) -            return f(*real_args, **(bind_kwargs | kwargs)) +            return func(*real_args, **(bind_kwargs | kwargs)) -        return bound +        return bound_func      @staticmethod -    def chain(*fs: Callable) -> Callable: -        if len(fs) == 0: +    def chain(*funcs: Callable) -> Callable: +        if len(funcs) == 0:              raise ValueError("At least one function is required!") -        rf = fs[0] -        for f in fs[1:]: -            def n(*args, **kwargs): -                r = rf(*args, **kwargs) -                r = r if isinstance(r, tuple) else (r,) -                return f(*r) -            rf = n -        return rf +        final_func = funcs[0] +        for func in funcs[1:]: +            func_copy = func -    @staticmethod -    def chain_single(f: Callable[P, R], f1: Callable[P1, R1], *bind_args, **bind_kwargs) -> \ -            Callable[ -                P, R1]: -        return MetaFunction.chain(f, MetaFunction.bind(f1, *bind_args, **bind_kwargs)) +            def chained_func(*args, **kwargs): +                results = final_func(*args, **kwargs) +                results = results if isinstance(results, tuple) else (results,) +                return func_copy(*results) -    convert_r = chain_single +            final_func = chained_func -    @staticmethod -    def neg(f: Callable[P, bool]) -> Callable[P, bool]: -        return MetaFunction.convert_r(f, RawFunctions.not_) +        return final_func  # Advanced Function Wrapper  class CruFunction: -    def __init__(self, f): +    def __init__(self, f: Callable):          self._f = f      @property      def f(self) -> Callable:          return self._f +    @property +    def func(self) -> Callable: +        return self.f +      def bind(self, *bind_args, **bind_kwargs) -> "CruFunction": -        self._f = MetaFunction.bind(self._f, *bind_args, **bind_kwargs) +        self._f = CruFunctionMeta.bind(self._f, *bind_args, **bind_kwargs)          return self -    def chain(self, *fs: Callable) -> "CruFunction": -        self._f = MetaFunction.chain(self._f, *fs) +    def chain(self, *funcs: Callable) -> "CruFunction": +        self._f = CruFunctionMeta.chain(self._f, *funcs)          return self -    def chain_single(self, f: Callable[P, R], f1: Callable[P1, R1], *bind_args, -                     **bind_kwargs) -> "CruFunction": -        self._f = MetaFunction.chain_single(self._f, f, f1, *bind_args, **bind_kwargs) -        return self +    def __call__(self, *args, **kwargs): +        return self._f(*args, **kwargs) -    def convert_r(self, f: Callable[P, R], f1: Callable[P1, R1], *bind_args, -                  **bind_kwargs) -> "CruFunction": -        self._f = MetaFunction.convert_r(self._f, f, f1, *bind_args, **bind_kwargs) -        return self +    @staticmethod +    def make_chain(base_func: Callable, *funcs: Callable) -> "CruFunction": +        return CruFunction(base_func).chain(*funcs) -    def neg(self) -> "CruFunction": -        self._f = MetaFunction.neg(self._f) -        return self -    def __call__(self, *args, **kwargs): -        return self._f(*args, **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_chain(*fs: Callable) -> Callable[P, R1]: -        return CruFunction(MetaFunction.chain(*fs)) - - -class WrappedFunctions: -    none = CruFunction(RawFunctions.none) -    true = CruFunction(RawFunctions.true) -    false = CruFunction(RawFunctions.false) -    identity = CruFunction(RawFunctions.identity) -    only_you = CruFunction(RawFunctions.only_you) -    equal = CruFunction(RawFunctions.equal) -    not_equal = CruFunction(RawFunctions.not_equal) -    not_ = CruFunction(RawFunctions.not_) +    def make_isinstance_of_types(*types: type) -> Callable: +        return CruFunction(lambda v: type(v) in types) + +CRU.add_objects(CruRawFunctions, CruFunctionMeta, CruFunction, CruWrappedFunctions, CruFunctionGenerators) | 
