blob: f5c2d7472a2fdb0216f2ba2c2d04abc9a7543968 (
plain) (
blame)
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
|
---@class Failure
---@field error any
local Failure = {}
Failure.__index = Failure
function Failure.new(error)
return setmetatable({ error = error }, Failure)
end
---@class Result
---@field value any
local Result = {}
Result.__index = Result
function Result.new(value)
return setmetatable({
value = value,
}, Result)
end
function Result.success(value)
return Result.new(value)
end
function Result.failure(error)
return Result.new(Failure.new(error))
end
function Result:get_or_nil()
if self:is_success() then
return self.value
end
end
function Result:get_or_else(value)
if self:is_success() then
return self.value
else
return value
end
end
---@param exception any @(optional) The exception to throw if the result is a failure.
function Result:get_or_throw(exception)
if self:is_success() then
return self.value
else
if exception ~= nil then
error(exception, 2)
else
error(self.value.error, 2)
end
end
end
function Result:err_or_nil()
if self:is_failure() then
return self.value.error
end
end
function Result:is_failure()
return getmetatable(self.value) == Failure
end
function Result:is_success()
return getmetatable(self.value) ~= Failure
end
---@param mapper_fn fun(value: any): any
function Result:map(mapper_fn)
if self:is_success() then
return Result.success(mapper_fn(self.value))
else
return self
end
end
---@param mapper_fn fun(value: any): any
function Result:map_catching(mapper_fn)
if self:is_success() then
local ok, result = pcall(mapper_fn, self.value)
if ok then
return Result.success(result)
else
return Result.failure(result)
end
else
return self
end
end
---@param recover_fn fun(value: any): any
function Result:recover(recover_fn)
if self:is_failure() then
return Result.success(recover_fn(self:err_or_nil()))
else
return self
end
end
---@param recover_fn fun(value: any): any
function Result:recover_catching(recover_fn)
if self:is_failure() then
local ok, value = pcall(recover_fn, self:err_or_nil())
if ok then
return Result.success(value)
else
return Result.failure(value)
end
else
return self
end
end
---@param fn fun(): any
---@return Result
function Result.run_catching(fn)
local ok, result = pcall(fn)
if ok then
return Result.success(result)
else
return Result.failure(result)
end
end
return Result
|