forked from samber/mo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoption.go
128 lines (103 loc) · 2.68 KB
/
option.go
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
package mo
import "fmt"
var optionNoSuchElement = fmt.Errorf("no such element")
// Some builds an Option when value is present.
func Some[T any](value T) Option[T] {
return Option[T]{
isPresent: true,
value: value,
}
}
// None builds an Option when value is absent.
func None[T any]() Option[T] {
return Option[T]{
isPresent: false,
}
}
func TupleToOption[T any](value T, ok bool) Option[T] {
if ok {
return Some(value)
}
return None[T]()
}
// Option is a container for an optional value of type T. If value exists, Option is
// of type Some. If the value is absent, Option is of type None.
type Option[T any] struct {
isPresent bool
value T
}
// IsPresent returns true when value is absent.
func (o Option[T]) IsPresent() bool {
return o.isPresent
}
// IsAbsent returns true when value is present.
func (o Option[T]) IsAbsent() bool {
return !o.isPresent
}
// Size returns 1 when value is present or 0 instead.
func (o Option[T]) Size() int {
if o.isPresent {
return 1
}
return 0
}
// Get returns value and presence.
func (o Option[T]) Get() (T, bool) {
if !o.isPresent {
return empty[T](), false
}
return o.value, true
}
// MustGet returns value if present or panics instead.
func (o Option[T]) MustGet() T {
if !o.isPresent {
panic(optionNoSuchElement)
}
return o.value
}
// OrElse returns value if present or default value.
func (o Option[T]) OrElse(fallback T) T {
if !o.isPresent {
return fallback
}
return o.value
}
// OrEmpty returns value if present or empty value.
func (o Option[T]) OrEmpty() T {
return o.value
}
// ForEach executes the given side-effecting function of value is present.
func (o Option[T]) ForEach(onValue func(value T)) {
if o.isPresent {
onValue(o.value)
}
}
// Match executes the first function if value is present and second function if absent.
// It returns a new Option.
func (o Option[T]) Match(onValue func(value T) (T, bool), onNone func() (T, bool)) Option[T] {
if o.isPresent {
return TupleToOption(onValue(o.value))
}
return TupleToOption(onNone())
}
// Map executes the mapper function if value is present or returns None if absent.
func (o Option[T]) Map(mapper func(value T) (T, bool)) Option[T] {
if o.isPresent {
return TupleToOption(mapper(o.value))
}
return None[T]()
}
// MapNone executes the mapper function if value is absent or returns Option.
func (o Option[T]) MapNone(mapper func() (T, bool)) Option[T] {
if o.isPresent {
return Some(o.value)
}
return TupleToOption(mapper())
}
// FlatMap executes the mapper function if value is present or returns None if absent.
func (o Option[T]) FlatMap(mapper func(value T) Option[T]) Option[T] {
if o.isPresent {
return mapper(o.value)
}
return None[T]()
}