Files
jpacrepo-uploader/jpacrepo_uploader/maybe.py
2023-09-04 07:36:50 +08:00

73 lines
1.9 KiB
Python

from __future__ import annotations
from typing import TypeVar, Generic, Optional, Callable, Any
T = TypeVar('T')
U = TypeVar('U')
class Maybe(Generic[T]):
def __init__(self, value: Optional[T] = None):
self._value: Optional[T] = value
@staticmethod
def of(obj: T) -> Maybe[T]:
return Maybe(obj)
@staticmethod
def of_nullable(obj: Optional[T]) -> Maybe[T]:
return Maybe(obj)
@staticmethod
def empty() -> Maybe[U]:
return _empty
@property
def value(self) -> T:
value = self._value
if not value:
raise ValueError('Empty Maybe')
else:
return value
@property
def is_present(self) -> bool:
return self._value is not None
@property
def is_empty(self) -> bool:
return not self.is_present
def map(self, transformer: Callable[[T], U]) -> Maybe[U]:
result: Maybe[U]
if self.is_present:
result = Maybe(transformer(self.value))
else:
result = Maybe.empty()
return result
def filter(self, predicate: Callable[[T], bool]) -> Maybe[T]:
return self if self.is_present and predicate(self.value) else Maybe.empty()
def flat_map(self, transformer: Callable[[T], Maybe[U]]) -> Maybe[U]:
return transformer(self.value) if self.is_present else Maybe.empty()
def or_else(self, alt: T) -> T:
return self.value if self.is_present else alt
def or_else_throw(self, supplier: Callable[[], Exception]) -> T:
if self.is_present:
return self.value
else:
raise supplier()
def or_else_get(self, supplier: Callable[[], T]) -> Maybe[T]:
return self if self.is_present else Maybe.of_nullable(supplier())
def if_present(self, callback: Callable[[T], U]) -> None:
if self.is_present:
callback(self.value)
_empty: Maybe[Any] = Maybe(None)