1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
## std/results: Result types.
## This module is imported by default.
import std/[options, format]
## The Result type.
## A type that represents either success or failure.
pub type Result[T, E] = union
Okay: T
Error: E
## The Err interface. Useful for dynamically dispatching errors.
pub type Err = interface
str(Self): str
dbg(Self): str
## A `Result` type that uses dynamically dispatched errors.
## The `Error` may be any type implementing `Err`.
pub type Result[T] = Result[T, ref Err]
## A `Result` type that only checks for success.
## Does not contain a value.
pub type Success[E] = Result[Unit, E]
## Checks if a `Result` type was successful.
pub func is_ok[T, E](self: Result[T, E]): bool =
self of Okay(_)
## Checks if a `Result` type was not successful.
pub func is_err[T, E](self: Result[T, E]): bool =
self of Error(_)
## Converts from a `Result[T, E]` to an `Option[T]`.
pub func ok[T, E](self: Result[T, E]): Option[T] =
if self of Okay(x):
Some(x)
else:
None()
## Converts from a `Result[T, E]` to an `Option[E]`.
pub func err[T, E](self: Result[T, E]): Option[E] =
if self of Error(x):
Some(x)
else:
None()
## Applies a function to `T`, if self is `Okay`.
pub func map[T, E, U](self: Result[T, E], fn: T -> U): Result[U, E] =
match self
of Okay(x):
Okay(fn(x))
of Error(e):
Error(e)
## Applies a function to `E`, if self is `Error`.
pub func map_err[T, E, F](self: Result[T, E], fn: E -> F): Result[T, F] =
match self
of Error(e):
Error(e.fn)
of Okay(x):
Okay(x)
## Applies a function to `T`, if it exists. Equivalent to `self.map(fn).flatten`.
pub func flatmap[T, E, U](self: Result[T, E], fn: T -> Result[U, E]): Result[U, E] =
match self
of Okay(x):
fn(x)
of Error(e):
Error(e)
## Converts from a `Result[Result[T, E], E]` to a `Result[T, E]`.
pub func flatten[T, E](self: Result[Result[T, E], E]): Result[T, E] =
match self
of Okay(Okay(x)):
Okay(x)
of Okay(Error(e)), Error(e):
Error(e)
## Transposes a `Result[Option[T], E]` to an `Option[Result[T, E]]`.
pub func transpose[T, E](self: Result[Option[T], E]): Option[Result[T, E]] =
match self
of Okay(Some(x)):
Some(Okay(x))
of Okay(None()), Error(_):
None()
## Transposes an `Option[Result[T, E]]` to a `Result[Option[T], E]`. Takes a default error.
pub func transpose[T, E](self: Option[Result[T, E]], error: E): Result[Option[T], E] =
match self
of Some(Okay(x)):
Okay(Some(x))
of Some(Error(e)):
Error(e)
of None():
Error(error)
## Returns the inner value or a default.
pub func get_or[T, E](self: Result[T, E], default: T): T =
if self of Okay(x): x
else: default
## Directly accesses the inner value. Throws an exception if `Error`.
pub yeet func `!`[T, E](self: Result[T, E]): T =
match self
of Okay(x): x
of Error(e): raise Exception(e) # todo: syntax??
pub yeet func get_err[T, E](self: Result[T, E]): E =
match self
of Error(e): e
of Okay(x): raise Exception(x) # todo: syntax??
## Indirect access. Propagates `Error`.
macro `?`[T, E](self: Result[T, E]) =
quote:
match self
of Okay(x): x
of Error(e): return Error(e)
## Overloads the `==` operation for use on Results.
pub func `==`[T, E, F](a: Result[T, E], b: Result[T, F]): bool =
match (a, b)
of (Okay(x), Okay(y)):
x == y
of _:
false
## Overloads the `str()` function for use on Results.
pub func str[T, E](self: Result[T, E]): str =
match self
of Some(x):
fmt("Okay({})", x.str)
of Error(e):
fmt("Error({})", e.str)
examples:
let x: Error("fuck") = Okay(42)
func idk: Result[int, string]
# references:
# https://doc.rust-lang.org/std/result/enum.Result.html
# https://github.com/arnetheduck/nim-results
# https://github.com/codex-storage/questionable
|