1from __future__ import annotations
2
3from typing import TYPE_CHECKING, Callable, TypeVar, Union
4
5from stdlibx.result._errors import ResultExpectError, ResultUnwrapError
6from stdlibx.result._result import error, is_err, is_ok, ok
7from typing_extensions import TypeVarTuple, Unpack
8
9if TYPE_CHECKING:
10 from stdlibx.result.types import Result
11
12T = TypeVar("T")
13E = TypeVar("E")
14U = TypeVar("U")
15F = TypeVar("F")
16Ts = TypeVarTuple("Ts")
17_AnyException = TypeVar("_AnyException", bound=Exception)
18
19
[docs]
20def is_ok_and(result: Result[T, E], func: Callable[[T], bool]) -> bool:
21 return is_ok(result) and func(result.value)
22
23
[docs]
24def is_err_and(result: Result[T, E], func: Callable[[E], bool]) -> bool:
25 return is_err(result) and func(result.error)
26
27
[docs]
28def map_(result: Result[T, E], func: Callable[[T], U]) -> Result[U, E]:
29 if is_ok(result):
30 return ok(func(result.value))
31 return error(result.error)
32
33
[docs]
34def map_or(result: Result[T, E], default: U, func: Callable[[T], U]) -> U:
35 if is_ok(result):
36 return func(result.value)
37 return default
38
39
[docs]
40def map_or_else(
41 result: Result[T, E], default: Callable[[E], U], func: Callable[[T], U]
42) -> U:
43 if is_ok(result):
44 return func(result.value)
45 return default(result.error)
46
47
[docs]
48def map_err(result: Result[T, E], func: Callable[[E], F]) -> Result[T, F]:
49 if is_err(result):
50 return error(func(result.error))
51 return ok(result.value)
52
53
[docs]
54def inspect(result: Result[T, E], func: Callable[[T], None]) -> Result[T, E]:
55 if is_ok(result):
56 func(result.value)
57 return result
58
59
[docs]
60def inspect_err(result: Result[T, E], func: Callable[[E], None]) -> Result[T, E]:
61 if is_err(result):
62 func(result.error)
63 return result
64
65
[docs]
66def expect(result: Result[T, E], msg: str) -> T:
67 if is_ok(result):
68 return result.value
69
70 _msg = f"{msg}: {result.error}"
71 raise ResultExpectError(_msg)
72
73
[docs]
74def unwrap(result: Result[T, E]) -> T:
75 if is_ok(result):
76 return result.value
77
78 _msg = f"{result.error}"
79 raise ResultUnwrapError(_msg)
80
81
[docs]
82def expect_err(result: Result[T, E], msg: str) -> E:
83 if is_err(result):
84 return result.error
85
86 _msg = f"{msg}: {result.value}"
87 raise ResultExpectError(_msg)
88
89
[docs]
90def unwrap_err(result: Result[T, E]) -> E:
91 if is_err(result):
92 return result.error
93
94 _msg = f"{result.value}"
95 raise ResultUnwrapError(_msg)
96
97
[docs]
98def and_(result: Result[T, E], other: Result[U, F]) -> Result[U, Union[E, F]]:
99 if is_ok(result):
100 return other # type: ignore
101 return error(result.error)
102
103
[docs]
104def and_then(
105 result: Result[T, E], func: Callable[[T], Result[U, F]]
106) -> Result[U, Union[E, F]]:
107 if is_ok(result):
108 return func(result.value) # type: ignore
109 return error(result.error)
110
111
[docs]
112def or_(result: Result[T, E], default: Result[T, F]) -> Result[T, F]:
113 if is_ok(result):
114 return ok(result.value)
115 return default
116
117
[docs]
118def or_else(result: Result[T, E], default: Callable[[E], Result[T, F]]) -> Result[T, F]:
119 if is_err(result):
120 return default(result.error)
121 return ok(result.value)
122
123
[docs]
124def unwrap_or(result: Result[T, E], default: T) -> T:
125 if is_ok(result):
126 return result.value
127 return default
128
129
[docs]
130def unwrap_or_else(result: Result[T, E], default: Callable[[E], T]) -> T:
131 if is_ok(result):
132 return result.value
133 return default(result.error)
134
135
[docs]
136def unwrap_or_raise(result: Result[T, _AnyException]) -> T:
137 if is_ok(result):
138 return result.value
139 raise result.error
140
141
[docs]
142def flatten(result: Result[Result[T, E], F]) -> Result[T, Union[E, F]]:
143 if is_ok(result):
144 return result.value # type: ignore
145 return error(result.error)
146
147
[docs]
148def zipped(
149 result: Result[tuple[Unpack[Ts]], E], func: Callable[[Unpack[Ts]], Result[U, E]]
150) -> Result[tuple[Unpack[Ts], U], E]:
151 if is_ok(result):
152 return map_(func(*result.value), lambda val: (*result.value, val))
153 return error(result.error)