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
136
137
138
139
|
## std.results: Result types.
## This module is imported by default.
use std.[options, format]
## The Result type. Represents either success or failure.
pub type Result[T, E] = union
Okay(T)
Error(E)
## The Err class. Useful for dynamically dispatching errors.
pub type Err = class
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[void, E]
## A `Result` type that only checks for success.
## Does not contain a value. Dynamically dispatched.
# pub type Success = Result[void]
## Syntactic sugar for dynamic result type declarations.
pub macro !(T: type) =
quote Result[`T`]
## Indirect access. Propagates `Error`.
pub macro ?[T, E](self: Result[T, E]) =
quote
match `self`
of Okay(x) then x
of Error(e) then return Error(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]): T? =
if self of Okay(x) then
Some(x)
else
None
## Converts from a `Result[T, E]` to an `Option[E]`.
pub func err[T, E](self: Result[T, E]): E? =
if self of Error(x) then
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) then
Okay(fn(x))
of Error(e) then
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) then
Error(fn(e))
of Okay(x) then
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) then
fn(x)
of Error(e) then
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)) then
Okay(x)
of Okay(Error(e)), Error(e) then
Error(e)
## Transposes a `Result[Option[T], E]` to an `Option[Result[T, E]]`.
pub func transpose[T, E](self: Result[T?, E]): Result[T, E]? =
match self
of Okay(Some(x)) then
Some(Okay(x))
of Okay(None), Error(_) then
None
## Transposes an `Option[Result[T, E]]` to a `Result[Option[T], E]`. Takes a default error.
pub func transpose[T, E](self: Result[T, E]?, error: E): Result[T?, E] =
match self
of Some(Okay(x)) then Okay(Some(x))
of Some(Error(e)) then Error(e)
of None then 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) then x
else default
## Directly accesses the inner value. Throws an exception if `Error`.
pub func ![T, E](self: Result[T, E]): T =
match self
of Okay(x) then x
of Error(e) then raise e
## Directly accesses the inner error. Throws an exception of type T if `Okay`.
pub func get_err[T, E](self: Result[T, E]): E =
match self
of Error(e) then e
of Okay(x) then raise x
## Overloads the `==` operation for use on Results.
pub func ==[T, E, F](a: Result[T, E], b: Result[T, F]): bool =
if (a, b) of (Okay(x), Okay(y)) then
x == y
else
false
## Overloads the `str()` function for use on Results.
pub func str[T: Display, E: Display](self: Result[T, E]): str =
match self
of Some(x) then
"Okay({})".fmt(x.str)
of Error(e) then
"Error({})".fmt(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
|