advent-2022-python/advent/parser/result.py
Ruediger Ludwig a355de5d8b Initial
2022-11-30 19:39:52 +01:00

109 lines
2.3 KiB
Python

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Callable, Generic, Never, TypeVar
S = TypeVar("S", covariant=True)
S1 = TypeVar("S1")
S2 = TypeVar("S2")
S3 = TypeVar("S3")
class Result(ABC, Generic[S]):
@staticmethod
def of(value: S1) -> Result[S1]:
return Success(value)
@staticmethod
def fail(failure: str) -> Result[Any]:
return Failure(failure)
@abstractmethod
def is_ok(self) -> bool:
pass
@abstractmethod
def is_fail(self) -> bool:
pass
@abstractmethod
def fmap(self, func: Callable[[S], S2]) -> Result[S2]:
pass
@abstractmethod
def bind(self, func: Callable[[S], Result[S2]]) -> Result[S2]:
pass
@abstractmethod
def get(self) -> S:
pass
@abstractmethod
def get_or(self, default: S1) -> S | S1:
pass
@abstractmethod
def get_or_else(self, default: Callable[[], S]) -> S:
pass
@abstractmethod
def get_error(self) -> str:
pass
class Success(Result[S]):
def __init__(self, value: S):
self.value = value
def is_ok(self) -> bool:
return True
def is_fail(self) -> bool:
return False
def fmap(self, func: Callable[[S], S2]) -> Result[S2]:
return Result.of(func(self.value)) # type: ignore
def bind(self, func: Callable[[S], Result[S2]]) -> Result[S2]:
return func(self.value)
def get(self) -> S:
return self.value
def get_or(self, default: S1) -> S | S1:
return self.value
def get_or_else(self, default: Callable[[], S]) -> S:
return self.value
def get_error(self) -> Never:
raise Exception("No Error in Success Value")
class Failure(Result[Any]):
def __init__(self, value: str):
self.value = value
def is_ok(self) -> bool:
return False
def is_fail(self) -> bool:
return True
def fmap(self, func: Callable[[Any], S2]) -> Result[S2]:
return self
def bind(self, func: Callable[[Any], Result[S2]]) -> Result[S2]:
return self
def get(self) -> Never:
raise Exception("No value in Fail")
def get_or(self, default: S1) -> S1:
return default
def get_or_else(self, default: Callable[[], S]) -> S:
return default()
def get_error(self) -> str:
return self.value