aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-core/optional.lua
blob: bb1683248d5e88bdf64fc2c34760b298164ee71c (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
128
129
130
131
132
133
134
135
136
---@class Optional<T>
---@field private _value unknown
local Optional = {}
Optional.__index = Optional

---@param value any
function Optional:new(value)
    ---@type Optional
    local instance = {}
    setmetatable(instance, self)
    instance._value = value
    return instance
end

local EMPTY = Optional:new(nil)

---@param value any
function Optional.of_nilable(value)
    if value == nil then
        return EMPTY
    else
        return Optional:new(value)
    end
end

function Optional.empty()
    return EMPTY
end

---@param value any
function Optional.of(value)
    return Optional:new(value)
end

---@param mapper_fn fun(value: any): any
function Optional:map(mapper_fn)
    if self:is_present() then
        return Optional.of_nilable(mapper_fn(self._value))
    else
        return EMPTY
    end
end

function Optional:get()
    if not self:is_present() then
        error("No value present.", 2)
    end
    return self._value
end

---@param value any
function Optional:or_else(value)
    if self:is_present() then
        return self._value
    else
        return value
    end
end

---@param supplier fun(): any
function Optional:or_else_get(supplier)
    if self:is_present() then
        return self._value
    else
        return supplier()
    end
end

---@param supplier fun(value: any): Optional
---@return Optional
function Optional:and_then(supplier)
    if self:is_present() then
        return supplier(self._value)
    else
        return self
    end
end

---@param supplier fun(): Optional
---@return Optional
function Optional:or_(supplier)
    if self:is_present() then
        return self
    else
        return supplier()
    end
end

---@param exception any? The exception to throw if the result is a failure.
function Optional:or_else_throw(exception)
    if self:is_present() then
        return self._value
    else
        if exception then
            error(exception, 2)
        else
            error("No value present.", 2)
        end
    end
end

---@param fn fun(value: any)
function Optional:if_present(fn)
    if self:is_present() then
        fn(self._value)
    end
    return self
end

---@param fn fun(value: any)
function Optional:if_not_present(fn)
    if not self:is_present() then
        fn(self._value)
    end
    return self
end

function Optional:is_present()
    return self._value ~= nil
end

---@param err (fun(): any)|string
function Optional:ok_or(err)
    local Result = require "mason-core.result"
    if self:is_present() then
        return Result.success(self:get())
    else
        if type(err) == "string" then
            return Result.failure(err)
        else
            return Result.failure(err())
        end
    end
end

return Optional