From 346140d675cd7c74d077a34da6eb5a95a1643000 Mon Sep 17 00:00:00 2001 From: rus07tam Date: Sun, 23 Nov 2025 10:30:34 +0000 Subject: [PATCH] feat: add map(), and_then(), or_else() in UniqueType --- src/snakia/types/unique.py | 39 +++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/snakia/types/unique.py b/src/snakia/types/unique.py index 2b3f52f..454b177 100644 --- a/src/snakia/types/unique.py +++ b/src/snakia/types/unique.py @@ -1,6 +1,8 @@ -from typing import Any, TypeVar, final +from typing import Any, Callable, TypeGuard, TypeVar, final T = TypeVar("T") +V = TypeVar("V") +R = TypeVar("R") @final @@ -36,6 +38,41 @@ class UniqueType(type): def __call__(cls: type[T]) -> T: return cls.__new__(cls) # noqa: E1120 # pylint: disable=E1120 + def __hash__(cls) -> int: + return id(cls) + + def itis(cls: type[T], value: Any) -> TypeGuard[T]: + return value is cls or isinstance(value, cls) + + def unwrap(cls: type[T], value: V | type[T] | T, /) -> V: + if value is cls or isinstance(value, cls): + raise TypeError(f"Expected {cls}, got {value}") + return value # type: ignore + + def map( + cls: type[T], + value: V | type[T] | T, + and_then: Callable[[V], R], + or_else: Callable[[type[T]], R], + ) -> R: + if value is cls or isinstance(value, cls): + return and_then(value) # type: ignore + return or_else(cls) + + def and_then( + cls: type[T], value: V | type[T] | T, func: Callable[[V], R] + ) -> type[T] | R: + if value is cls or isinstance(value, cls): + return cls + return func(value) # type: ignore + + def or_else( + cls: type[T], value: V | type[T] | T, func: Callable[[type[T]], R] + ) -> R | V: + if value is cls or isinstance(value, cls): + return func(cls) + return value # type: ignore + class Unique(metaclass=UniqueType): # noqa: R0903 # pylint: disable=R0903 """