Initial
This commit is contained in:
commit
a355de5d8b
24 changed files with 1133 additions and 0 deletions
109
advent/parser/result.py
Normal file
109
advent/parser/result.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue