Source code for stdlibx.result._result
1from __future__ import annotations
2
3from functools import wraps
4from typing import TYPE_CHECKING, Callable, Generic, Literal, TypeVar
5
6from stdlibx.result.types import Error, Ok
7from typing_extensions import ParamSpec, TypeIs
8
9if TYPE_CHECKING:
10 from stdlibx.result.types import Operation, Result
11
12T = TypeVar("T")
13E = TypeVar("E")
14U = TypeVar("U")
15P = ParamSpec("P")
16
17
[docs]
18def ok(value: T) -> Result[T, E]:
19 return _Ok(value)
20
21
[docs]
22def error(error: E) -> Result[T, E]:
23 return _Error(error)
24
25
[docs]
26def is_ok(result: Result[T, E]) -> TypeIs[Ok[T]]:
27 return result.is_ok()
28
29
[docs]
30def is_err(result: Result[T, E]) -> TypeIs[Error[E]]:
31 return result.is_err()
32
33
[docs]
34def try_(
35 func: Callable[P, T], *args: P.args, **kwargs: P.kwargs
36) -> Result[T, Exception]:
37 try:
38 return ok(func(*args, **kwargs))
39 except Exception as e:
40 return error(e)
41
42
[docs]
43def safe(func: Callable[P, T]) -> Callable[P, Result[T, Exception]]:
44 @wraps(func)
45 def _wrapped(*args: P.args, **kwargs: P.kwargs) -> Result[T, Exception]:
46 try:
47 return ok(func(*args, **kwargs))
48 except Exception as e:
49 return error(e)
50
51 return _wrapped
52
53
54class _Ok(Generic[T]):
55 __match_args__ = ("value",)
56 __slots__ = ("value",)
57
58 value: T
59
60 def __init__(self, value: T) -> None:
61 self.value = value
62
63 def __repr__(self) -> str:
64 return f"Ok({self.value!r})"
65
66 def __eq__(self, other: object) -> bool:
67 if isinstance(other, Ok):
68 return other.value == self.value
69 return False
70
71 def is_ok(self) -> Literal[True]:
72 return True
73
74 def is_err(self) -> Literal[False]:
75 return False
76
77 def apply(self, operation: Operation[Result[T, E], U]) -> U:
78 return operation(self)
79
80
81class _Error(Generic[E]):
82 __match_args__ = ("error",)
83 __slots__ = ("error",)
84
85 error: E
86
87 def __init__(self, error: E) -> None:
88 self.error = error
89
90 def __repr__(self) -> str:
91 return f"Error({self.error!r})"
92
93 def __eq__(self, other: object) -> bool:
94 if isinstance(other, Error):
95 return other.error == self.error
96 return False
97
98 def is_ok(self) -> Literal[False]:
99 return False
100
101 def is_err(self) -> Literal[True]:
102 return True
103
104 def apply(self, operation: Operation[Result[T, E], U]) -> U:
105 return operation(self)