-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
Copy pathoptional.go
62 lines (50 loc) · 1.64 KB
/
optional.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
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package optional // import "go.opentelemetry.io/collector/confmap/optional"
import "go.opentelemetry.io/collector/confmap"
// Optional is a type that can be used to represent a value that may or may not be present.
// It supports three flavors: Some(value), None(), and WithDefault(defaultValue).
type Optional[T any] struct {
hasValue bool
value T
defaultFn DefaultFunc[T]
}
type DefaultFunc[T any] func() T
var _ confmap.Unmarshaler = (*Optional[any])(nil)
// Some creates an Optional with a value.
func Some[T any](value T) Optional[T] {
return Optional[T]{value: value, hasValue: true}
}
// None creates an Optional with no value.
func None[T any]() Optional[T] {
return Optional[T]{}
}
// WithDefault creates an Optional which has no value
// unless user config provides some, in which case
// the defaultFn is used to create the initial value,
// which may be overridden by the user provided config.
//
// The reason we pass a function instead of T directly
// is to allow this to work with T being a pointer,
// because we wouldn't want to copy the value of a pointer
// since it might reuse (and override) some shared state.
func WithDefault[T any](defaultFn DefaultFunc[T]) Optional[T] {
return Optional[T]{defaultFn: defaultFn}
}
func (o Optional[T]) HasValue() bool {
return o.hasValue
}
func (o Optional[T]) Value() T {
return o.value
}
func (o *Optional[T]) Unmarshal(conf *confmap.Conf) error {
if o.defaultFn != nil {
o.value = o.defaultFn()
o.hasValue = true
}
if err := conf.Unmarshal(&o.value); err != nil {
return err
}
o.hasValue = true
return nil
}