rezult 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rezult-0.1.0/PKG-INFO +10 -0
- rezult-0.1.0/README.md +1 -0
- rezult-0.1.0/pyproject.toml +18 -0
- rezult-0.1.0/pyproject.toml.orig +17 -0
- rezult-0.1.0/src/rezult/__init__.py +7 -0
- rezult-0.1.0/src/rezult/option.py +269 -0
- rezult-0.1.0/src/rezult/result.py +262 -0
rezult-0.1.0/PKG-INFO
ADDED
rezult-0.1.0/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WIP
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "rezult"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[[project.authors]]
|
|
10
|
+
name = "Sequence"
|
|
11
|
+
email = "3863887959@qq.com"
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
rezult = "rezult:main"
|
|
15
|
+
|
|
16
|
+
[build-system]
|
|
17
|
+
requires = ["uv_build>=0.12.7,<0.13.0"]
|
|
18
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "rezult"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Sequence", email = "3863887959@qq.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = []
|
|
11
|
+
|
|
12
|
+
[project.scripts]
|
|
13
|
+
rezult = "rezult:main"
|
|
14
|
+
|
|
15
|
+
[build-system]
|
|
16
|
+
requires = ["uv_build>=0.12.7,<0.13.0"]
|
|
17
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import Any
|
|
6
|
+
from typing import Final
|
|
7
|
+
from typing import Never
|
|
8
|
+
from typing import Self
|
|
9
|
+
|
|
10
|
+
from .result import Err
|
|
11
|
+
from .result import Ok
|
|
12
|
+
from .result import UnwrapError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .result import Result
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
_UNSUPPORTED = NotImplementedError("Unsupported option type")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Option[T]:
|
|
23
|
+
def __init__(self) -> Never:
|
|
24
|
+
raise NotImplementedError("You should implement __init__ for the variant first.")
|
|
25
|
+
|
|
26
|
+
# ==========
|
|
27
|
+
# Assertions
|
|
28
|
+
# ==========
|
|
29
|
+
|
|
30
|
+
def is_some(self) -> bool:
|
|
31
|
+
return isinstance(self, Some)
|
|
32
|
+
|
|
33
|
+
def is_some_and(self, f: Callable[[T], bool]) -> bool:
|
|
34
|
+
match self:
|
|
35
|
+
case Some(value=value):
|
|
36
|
+
return f(value)
|
|
37
|
+
case Nothing():
|
|
38
|
+
return False
|
|
39
|
+
case _:
|
|
40
|
+
raise _UNSUPPORTED
|
|
41
|
+
|
|
42
|
+
def is_none(self) -> bool:
|
|
43
|
+
return not self.is_some()
|
|
44
|
+
|
|
45
|
+
def is_none_or(self, f: Callable[[T], bool]) -> bool:
|
|
46
|
+
match self:
|
|
47
|
+
case Some(value=value):
|
|
48
|
+
return f(value)
|
|
49
|
+
case Nothing():
|
|
50
|
+
return True
|
|
51
|
+
case _:
|
|
52
|
+
raise _UNSUPPORTED
|
|
53
|
+
|
|
54
|
+
# ========
|
|
55
|
+
# Castings
|
|
56
|
+
# ========
|
|
57
|
+
|
|
58
|
+
def ok_or[E](self, err: E) -> Result[T, E]:
|
|
59
|
+
match self:
|
|
60
|
+
case Some(value=value):
|
|
61
|
+
return Ok(value)
|
|
62
|
+
case Nothing():
|
|
63
|
+
return Err(err)
|
|
64
|
+
case _:
|
|
65
|
+
raise _UNSUPPORTED
|
|
66
|
+
|
|
67
|
+
def ok_or_else[E](self, op: Callable[[], E]) -> Result[T, E]:
|
|
68
|
+
match self:
|
|
69
|
+
case Some(value=value):
|
|
70
|
+
return Ok(value)
|
|
71
|
+
case Nothing():
|
|
72
|
+
return Err(op())
|
|
73
|
+
case _:
|
|
74
|
+
raise _UNSUPPORTED
|
|
75
|
+
|
|
76
|
+
# ========
|
|
77
|
+
# Mappings
|
|
78
|
+
# ========
|
|
79
|
+
|
|
80
|
+
def map[U](self, op: Callable[[T], U]) -> Option[U]:
|
|
81
|
+
match self:
|
|
82
|
+
case Some(value=value):
|
|
83
|
+
return Some(op(value))
|
|
84
|
+
case Nothing():
|
|
85
|
+
return Nothing()
|
|
86
|
+
case _:
|
|
87
|
+
raise _UNSUPPORTED
|
|
88
|
+
|
|
89
|
+
def map_or[U](self, default: U, f: Callable[[T], U]) -> U:
|
|
90
|
+
match self:
|
|
91
|
+
case Some(value=value):
|
|
92
|
+
return f(value)
|
|
93
|
+
case Nothing():
|
|
94
|
+
return default
|
|
95
|
+
case _:
|
|
96
|
+
raise _UNSUPPORTED
|
|
97
|
+
|
|
98
|
+
def map_or_else[U](self, default: Callable[[], U], f: Callable[[T], U]) -> U:
|
|
99
|
+
match self:
|
|
100
|
+
case Some(value=value):
|
|
101
|
+
return f(value)
|
|
102
|
+
case Nothing():
|
|
103
|
+
return default()
|
|
104
|
+
case _:
|
|
105
|
+
raise _UNSUPPORTED
|
|
106
|
+
|
|
107
|
+
# ===========
|
|
108
|
+
# Inspectings
|
|
109
|
+
# ===========
|
|
110
|
+
|
|
111
|
+
def inspect(self, f: Callable[[T], None]) -> Self:
|
|
112
|
+
if isinstance(self, Some):
|
|
113
|
+
f(self.value)
|
|
114
|
+
return self
|
|
115
|
+
|
|
116
|
+
# ==========
|
|
117
|
+
# Unwrapping
|
|
118
|
+
# ==========
|
|
119
|
+
|
|
120
|
+
def unwrap(self) -> T:
|
|
121
|
+
match self:
|
|
122
|
+
case Some(value=value):
|
|
123
|
+
return value
|
|
124
|
+
case Nothing():
|
|
125
|
+
raise UnwrapError("Called unwrap on a Nothing value")
|
|
126
|
+
case _:
|
|
127
|
+
raise _UNSUPPORTED
|
|
128
|
+
|
|
129
|
+
def unwrap_or(self, default: T) -> T:
|
|
130
|
+
match self:
|
|
131
|
+
case Some(value=value):
|
|
132
|
+
return value
|
|
133
|
+
case Nothing():
|
|
134
|
+
return default
|
|
135
|
+
case _:
|
|
136
|
+
raise _UNSUPPORTED
|
|
137
|
+
|
|
138
|
+
def unwrap_or_else(self, op: Callable[[], T]) -> T:
|
|
139
|
+
match self:
|
|
140
|
+
case Some(value=value):
|
|
141
|
+
return value
|
|
142
|
+
case Nothing():
|
|
143
|
+
return op()
|
|
144
|
+
case _:
|
|
145
|
+
raise _UNSUPPORTED
|
|
146
|
+
|
|
147
|
+
def expect(self, msg: str) -> T:
|
|
148
|
+
match self:
|
|
149
|
+
case Some(value=value):
|
|
150
|
+
return value
|
|
151
|
+
case Nothing():
|
|
152
|
+
raise UnwrapError(msg)
|
|
153
|
+
case _:
|
|
154
|
+
raise _UNSUPPORTED
|
|
155
|
+
|
|
156
|
+
# =========
|
|
157
|
+
# Filtering
|
|
158
|
+
# =========
|
|
159
|
+
|
|
160
|
+
def filter(self, predicate: Callable[[T], bool]) -> Option[T]:
|
|
161
|
+
match self:
|
|
162
|
+
case Some(value=value):
|
|
163
|
+
return self if predicate(value) else Nothing()
|
|
164
|
+
case Nothing():
|
|
165
|
+
return self
|
|
166
|
+
case _:
|
|
167
|
+
raise _UNSUPPORTED
|
|
168
|
+
|
|
169
|
+
# =========
|
|
170
|
+
# Operating
|
|
171
|
+
# =========
|
|
172
|
+
|
|
173
|
+
def and_opt[U](self, opt: Option[U]) -> Option[U]:
|
|
174
|
+
match self:
|
|
175
|
+
case Some():
|
|
176
|
+
return opt
|
|
177
|
+
case Nothing():
|
|
178
|
+
return Nothing()
|
|
179
|
+
case _:
|
|
180
|
+
raise _UNSUPPORTED
|
|
181
|
+
|
|
182
|
+
def and_then_opt[U](self, op: Callable[[T], Option[U]]) -> Option[U]:
|
|
183
|
+
match self:
|
|
184
|
+
case Some(value=value):
|
|
185
|
+
return op(value)
|
|
186
|
+
case Nothing():
|
|
187
|
+
return Nothing()
|
|
188
|
+
case _:
|
|
189
|
+
raise _UNSUPPORTED
|
|
190
|
+
|
|
191
|
+
def or_opt(self, opt: Option[T]) -> Option[T]:
|
|
192
|
+
match self:
|
|
193
|
+
case Some():
|
|
194
|
+
return self
|
|
195
|
+
case Nothing():
|
|
196
|
+
return opt
|
|
197
|
+
case _:
|
|
198
|
+
raise _UNSUPPORTED
|
|
199
|
+
|
|
200
|
+
def or_else_opt(self, op: Callable[[], Option[T]]) -> Option[T]:
|
|
201
|
+
match self:
|
|
202
|
+
case Some():
|
|
203
|
+
return self
|
|
204
|
+
case Nothing():
|
|
205
|
+
return op()
|
|
206
|
+
case _:
|
|
207
|
+
raise _UNSUPPORTED
|
|
208
|
+
|
|
209
|
+
def xor(self, opt: Option[T]) -> Option[T]:
|
|
210
|
+
match (self, opt):
|
|
211
|
+
case (Some() as some, Nothing()):
|
|
212
|
+
return some
|
|
213
|
+
case (Nothing(), Some() as some):
|
|
214
|
+
return some
|
|
215
|
+
case (Some(), Some()):
|
|
216
|
+
return Nothing()
|
|
217
|
+
case (Nothing(), Nothing()):
|
|
218
|
+
return Nothing()
|
|
219
|
+
case _:
|
|
220
|
+
raise _UNSUPPORTED
|
|
221
|
+
|
|
222
|
+
def zip[U](self, other: Option[U]) -> Option[tuple[T, U]]:
|
|
223
|
+
match (self, other):
|
|
224
|
+
case (Some(value=left), Some(value=right)):
|
|
225
|
+
return Some((left, right))
|
|
226
|
+
case (Some(), Nothing()) | (Nothing(), Some()) | (Nothing(), Nothing()):
|
|
227
|
+
return Nothing()
|
|
228
|
+
case _:
|
|
229
|
+
raise _UNSUPPORTED
|
|
230
|
+
|
|
231
|
+
# =============
|
|
232
|
+
# Transformings
|
|
233
|
+
# =============
|
|
234
|
+
|
|
235
|
+
@classmethod
|
|
236
|
+
def flatten(cls, option: Option[Option[T]]) -> Option[T]:
|
|
237
|
+
match option:
|
|
238
|
+
case Some(value=inner):
|
|
239
|
+
return inner
|
|
240
|
+
case Nothing():
|
|
241
|
+
return Nothing()
|
|
242
|
+
case _:
|
|
243
|
+
raise _UNSUPPORTED
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
def transpose[E](cls, option: Option[Result[T, E]]) -> Result[Option[T], E]:
|
|
247
|
+
match option:
|
|
248
|
+
case Some(value=Ok(value=value)):
|
|
249
|
+
return Ok(Some(value))
|
|
250
|
+
case Some(value=Err(value=value)):
|
|
251
|
+
return Err(value)
|
|
252
|
+
case Nothing():
|
|
253
|
+
return Ok(Nothing())
|
|
254
|
+
case _:
|
|
255
|
+
raise _UNSUPPORTED
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class Some[T](Option[T]):
|
|
259
|
+
__slots__ = ("value",)
|
|
260
|
+
|
|
261
|
+
def __init__(self, value: T) -> None:
|
|
262
|
+
self.value: Final = value
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class Nothing(Option[Any]):
|
|
266
|
+
__slots__ = ()
|
|
267
|
+
|
|
268
|
+
def __init__(self) -> None:
|
|
269
|
+
pass
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import Any
|
|
6
|
+
from typing import Final
|
|
7
|
+
from typing import Never
|
|
8
|
+
from typing import Self
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .option import Option
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
_UNSUPPORTED = NotImplementedError("Unsupported result type")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class UnwrapError(Exception):
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Result[T, E]:
|
|
23
|
+
def __init__(self) -> Never:
|
|
24
|
+
raise NotImplementedError("You should implement __init__ for the variant first.")
|
|
25
|
+
|
|
26
|
+
# ==========
|
|
27
|
+
# Assertions
|
|
28
|
+
# ==========
|
|
29
|
+
|
|
30
|
+
def is_ok(self) -> bool:
|
|
31
|
+
return isinstance(self, Ok)
|
|
32
|
+
|
|
33
|
+
def is_ok_and(self, f: Callable[[T], bool]) -> bool:
|
|
34
|
+
match self:
|
|
35
|
+
case Ok(value=value):
|
|
36
|
+
return f(value)
|
|
37
|
+
case Err():
|
|
38
|
+
return False
|
|
39
|
+
case _:
|
|
40
|
+
raise _UNSUPPORTED
|
|
41
|
+
|
|
42
|
+
def is_err(self) -> bool:
|
|
43
|
+
return not self.is_ok()
|
|
44
|
+
|
|
45
|
+
def is_err_and(self, f: Callable[[E], bool]) -> bool:
|
|
46
|
+
match self:
|
|
47
|
+
case Ok():
|
|
48
|
+
return False
|
|
49
|
+
case Err(value=value):
|
|
50
|
+
return f(value)
|
|
51
|
+
case _:
|
|
52
|
+
raise _UNSUPPORTED
|
|
53
|
+
|
|
54
|
+
# ========
|
|
55
|
+
# Castings
|
|
56
|
+
# ========
|
|
57
|
+
|
|
58
|
+
def ok(self) -> Option[T]:
|
|
59
|
+
from .option import Nothing
|
|
60
|
+
from .option import Some
|
|
61
|
+
|
|
62
|
+
match self:
|
|
63
|
+
case Ok(value=value):
|
|
64
|
+
return Some(value)
|
|
65
|
+
case Err():
|
|
66
|
+
return Nothing()
|
|
67
|
+
case _:
|
|
68
|
+
raise _UNSUPPORTED
|
|
69
|
+
|
|
70
|
+
def err(self) -> Option[E]:
|
|
71
|
+
from .option import Nothing
|
|
72
|
+
from .option import Some
|
|
73
|
+
|
|
74
|
+
match self:
|
|
75
|
+
case Ok():
|
|
76
|
+
return Nothing()
|
|
77
|
+
case Err(value=value):
|
|
78
|
+
return Some(value)
|
|
79
|
+
case _:
|
|
80
|
+
raise _UNSUPPORTED
|
|
81
|
+
|
|
82
|
+
# ========
|
|
83
|
+
# Mappings
|
|
84
|
+
# ========
|
|
85
|
+
|
|
86
|
+
def map[U](self, op: Callable[[T], U]) -> Result[U, E]:
|
|
87
|
+
match self:
|
|
88
|
+
case Ok(value=value):
|
|
89
|
+
return Ok(op(value))
|
|
90
|
+
case Err(value=value):
|
|
91
|
+
return Err(value)
|
|
92
|
+
case _:
|
|
93
|
+
raise _UNSUPPORTED
|
|
94
|
+
|
|
95
|
+
def map_or[U](self, default: U, f: Callable[[T], U]) -> U:
|
|
96
|
+
match self:
|
|
97
|
+
case Ok(value=value):
|
|
98
|
+
return f(value)
|
|
99
|
+
case Err():
|
|
100
|
+
return default
|
|
101
|
+
case _:
|
|
102
|
+
raise _UNSUPPORTED
|
|
103
|
+
|
|
104
|
+
def map_err[F](self, op: Callable[[E], F]) -> Result[T, F]:
|
|
105
|
+
match self:
|
|
106
|
+
case Ok(value=value):
|
|
107
|
+
return Ok(value)
|
|
108
|
+
case Err(value=value):
|
|
109
|
+
return Err(op(value))
|
|
110
|
+
case _:
|
|
111
|
+
raise _UNSUPPORTED
|
|
112
|
+
|
|
113
|
+
# ===========
|
|
114
|
+
# Inspectings
|
|
115
|
+
# ===========
|
|
116
|
+
|
|
117
|
+
def inspect(self, f: Callable[[T], None]) -> Self:
|
|
118
|
+
if isinstance(self, Ok):
|
|
119
|
+
f(self.value)
|
|
120
|
+
return self
|
|
121
|
+
|
|
122
|
+
def inspect_err(self, f: Callable[[E], None]) -> Self:
|
|
123
|
+
if isinstance(self, Err):
|
|
124
|
+
f(self.value)
|
|
125
|
+
return self
|
|
126
|
+
|
|
127
|
+
# ==========
|
|
128
|
+
# Unwrapping
|
|
129
|
+
# ==========
|
|
130
|
+
|
|
131
|
+
def unwrap(self) -> T:
|
|
132
|
+
match self:
|
|
133
|
+
case Ok(value=value):
|
|
134
|
+
return value
|
|
135
|
+
case Err(value=value):
|
|
136
|
+
raise UnwrapError(value)
|
|
137
|
+
case _:
|
|
138
|
+
raise _UNSUPPORTED
|
|
139
|
+
|
|
140
|
+
def unwrap_or(self, default: T) -> T:
|
|
141
|
+
match self:
|
|
142
|
+
case Ok(value=value):
|
|
143
|
+
return value
|
|
144
|
+
case Err():
|
|
145
|
+
return default
|
|
146
|
+
case _:
|
|
147
|
+
raise _UNSUPPORTED
|
|
148
|
+
|
|
149
|
+
def unwrap_or_else(self, op: Callable[[E], T]) -> T:
|
|
150
|
+
match self:
|
|
151
|
+
case Ok(value=value):
|
|
152
|
+
return value
|
|
153
|
+
case Err(value=value):
|
|
154
|
+
return op(value)
|
|
155
|
+
case _:
|
|
156
|
+
raise _UNSUPPORTED
|
|
157
|
+
|
|
158
|
+
def expect(self, msg: str) -> T:
|
|
159
|
+
match self:
|
|
160
|
+
case Ok(value=value):
|
|
161
|
+
return value
|
|
162
|
+
case Err():
|
|
163
|
+
raise UnwrapError(msg)
|
|
164
|
+
case _:
|
|
165
|
+
raise _UNSUPPORTED
|
|
166
|
+
|
|
167
|
+
def unwrap_err(self) -> E:
|
|
168
|
+
match self:
|
|
169
|
+
case Ok(value=value):
|
|
170
|
+
raise UnwrapError(value)
|
|
171
|
+
case Err(value=value):
|
|
172
|
+
return value
|
|
173
|
+
case _:
|
|
174
|
+
raise _UNSUPPORTED
|
|
175
|
+
|
|
176
|
+
def expect_err(self, msg: str) -> E:
|
|
177
|
+
match self:
|
|
178
|
+
case Ok():
|
|
179
|
+
raise UnwrapError(msg)
|
|
180
|
+
case Err(value=value):
|
|
181
|
+
return value
|
|
182
|
+
case _:
|
|
183
|
+
raise _UNSUPPORTED
|
|
184
|
+
|
|
185
|
+
# =========
|
|
186
|
+
# Operating
|
|
187
|
+
# =========
|
|
188
|
+
|
|
189
|
+
def and_res[U](self, res: Result[U, E]) -> Result[U, E]:
|
|
190
|
+
match self:
|
|
191
|
+
case Ok():
|
|
192
|
+
return res
|
|
193
|
+
case Err(value=value):
|
|
194
|
+
return Err(value)
|
|
195
|
+
case _:
|
|
196
|
+
raise _UNSUPPORTED
|
|
197
|
+
|
|
198
|
+
def and_then_res[U](self, op: Callable[[T], Result[U, E]]) -> Result[U, E]:
|
|
199
|
+
match self:
|
|
200
|
+
case Ok(value=value):
|
|
201
|
+
return op(value)
|
|
202
|
+
case Err(value=value):
|
|
203
|
+
return Err(value)
|
|
204
|
+
case _:
|
|
205
|
+
raise _UNSUPPORTED
|
|
206
|
+
|
|
207
|
+
def or_res[F](self, res: Result[T, F]) -> Result[T, F]:
|
|
208
|
+
match self:
|
|
209
|
+
case Ok(value=value):
|
|
210
|
+
return Ok(value)
|
|
211
|
+
case Err():
|
|
212
|
+
return res
|
|
213
|
+
case _:
|
|
214
|
+
raise _UNSUPPORTED
|
|
215
|
+
|
|
216
|
+
def or_else_res[F](self, op: Callable[[E], Result[T, F]]) -> Result[T, F]:
|
|
217
|
+
match self:
|
|
218
|
+
case Ok(value=value):
|
|
219
|
+
return Ok(value)
|
|
220
|
+
case Err(value=value):
|
|
221
|
+
return op(value)
|
|
222
|
+
case _:
|
|
223
|
+
raise _UNSUPPORTED
|
|
224
|
+
|
|
225
|
+
@classmethod
|
|
226
|
+
def transpose(cls, result: Result[Option[T], E]) -> Option[Result[T, E]]:
|
|
227
|
+
from .option import Nothing
|
|
228
|
+
from .option import Some
|
|
229
|
+
|
|
230
|
+
match result:
|
|
231
|
+
case Ok(value=Some(value=value)):
|
|
232
|
+
return Some(Ok(value))
|
|
233
|
+
case Ok(value=Nothing()):
|
|
234
|
+
return Nothing()
|
|
235
|
+
case Err(value=value):
|
|
236
|
+
return Some(Err(value))
|
|
237
|
+
case _:
|
|
238
|
+
raise _UNSUPPORTED
|
|
239
|
+
|
|
240
|
+
@classmethod
|
|
241
|
+
def flatten(cls, result: Result[Result[T, E], E]) -> Result[T, E]:
|
|
242
|
+
match result:
|
|
243
|
+
case Ok(value=inner):
|
|
244
|
+
return inner
|
|
245
|
+
case Err(value=value):
|
|
246
|
+
return Err(value)
|
|
247
|
+
case _:
|
|
248
|
+
raise _UNSUPPORTED
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class Ok[T](Result[T, Any]):
|
|
252
|
+
__slots__ = ("value",)
|
|
253
|
+
|
|
254
|
+
def __init__(self, value: T) -> None:
|
|
255
|
+
self.value: Final = value
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class Err[E](Result[Any, E]):
|
|
259
|
+
__slots__ = ("value",)
|
|
260
|
+
|
|
261
|
+
def __init__(self, value: E) -> None:
|
|
262
|
+
self.value: Final = value
|