aboutsummaryrefslogtreecommitdiffstats
path: root/lua/nvim-lsp-installer/core/result.lua
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