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