Documentation
¶
Overview ¶
Package optional provides a convenient and safe way to deal with options which may or may not have a designated value without using pointers and risking nil pointer dereferencing panics.
Index ¶
- Constants
- Variables
- func And[T comparable, O Optional[T]](left, right O) O
- func ClearIfMatch[T comparable](opt MutableOptional[T], probe T)
- func Equal[T comparable, O Optional[T]](left, right O) bool
- func GetOr[T comparable](opt Optional[T], val T) T
- func GetOrElse[T comparable](opt Optional[T], f func() T) T
- func GetOrInsert[T comparable](opt MutableOptional[T], val T) (T, error)
- func IsSomeAnd[T comparable](opt Option[T], f func(T) bool) bool
- func Or[T comparable, O Optional[T]](left, right O) O
- func SetDefaultExtraTimeFormats(formats []string)
- func TransformOr[T comparable](opt MutableOptional[T], t Transformer[T], backup T) error
- type Bool
- func (o Bool) MarshalText() (text []byte, err error)
- func (o *Bool) Scan(src any) error
- func (o *Bool) Set(str string) error
- func (o Bool) String() string
- func (o *Bool) True() bool
- func (o Bool) Type() string
- func (o *Bool) UnmarshalText(text []byte) error
- func (o Bool) Value() (driver.Value, error)
- type Byte
- type Duration
- func (o Duration) MarshalJSON() ([]byte, error)
- func (o Duration) MarshalText() (text []byte, err error)
- func (o *Duration) Scan(src any) error
- func (o *Duration) Set(str string) error
- func (o Duration) String() string
- func (o Duration) Type() string
- func (o *Duration) UnmarshalJSON(data []byte) error
- func (o *Duration) UnmarshalText(text []byte) error
- func (o Duration) Value() (driver.Value, error)
- type Float32
- type Float64
- type Int
- type Int8
- type Int16
- type Int32
- type Int64
- type LoadableOptional
- type MutableOptional
- type Option
- func (o *Option[T]) Clear()
- func (o Option[T]) Clone() Optional[T]
- func (o *Option[T]) Default(value T) (replaced bool)
- func (o Option[T]) Get() (val T, ok bool)
- func (o Option[T]) IsNone() bool
- func (o Option[T]) IsSome() bool
- func (o Option[T]) MarshalJSON() ([]byte, error)
- func (o Option[T]) Match(probe T) bool
- func (o Option[T]) MustGet() T
- func (o Option[T]) MutableClone() MutableOptional[T]
- func (o *Option[T]) Replace(value T) Optional[T]
- func (o *Option[T]) Transform(t Transformer[T]) error
- func (o *Option[T]) UnmarshalJSON(data []byte) error
- type Optional
- type OptionalError
- type Secret
- type StorableOptional
- type Str
- type Time
- func (o Time) Formats() []string
- func (o Time) MarshalJSON() ([]byte, error)
- func (o Time) MarshalText() (text []byte, err error)
- func (o *Time) Scan(src any) error
- func (o *Time) Set(str string) error
- func (o Time) String() string
- func (o Time) Type() string
- func (o *Time) UnmarshalJSON(data []byte) error
- func (o *Time) UnmarshalText(text []byte) error
- func (o Time) Value() (driver.Value, error)
- func (o Time) WithFormats(formats ...string) Time
- type Transformer
- type Uint
- type Uint8
- type Uint16
- type Uint32
- type Uint64
Constants ¶
const ( DEFAULT_TIME_FORMAT string = time.RFC3339Nano DEFAULT_TIME_STRING_FORMAT string = time.DateTime )
Variables ¶
Functions ¶
func And ¶
func And[T comparable, O Optional[T]](left, right O) O
And returns None if the first Optional is None, and the second Optional otherwise. Conceptually similar to left && right. This is a convenience function for Option selection. Convenient for merging configs, implementing builder patterns, etc.
func ClearIfMatch ¶
func ClearIfMatch[T comparable](opt MutableOptional[T], probe T)
ClearIfMatch calls clear if Optional.Match(probe) == true. This is a convenience for situations where you need to convert from a value of T with known "magic value" which implies None. A good example of this is if you have an int loaded from command line flags and you know that any flag omitted by the user will be assigned to 0. This can be done like this: o := Some(x) o.ClearIfMatch(0)
func Equal ¶
func Equal[T comparable, O Optional[T]](left, right O) bool
Equal is a convenience function for checking if the contents of two Optional types are equivilent. Note that Get() and Match() may be overridden by more complex types which wrap a vanilla Option. In these situations, the writer is responsible for making sure that the invariant Some(x).Match(Some(x).Get()) is always true.
func GetOr ¶
func GetOr[T comparable](opt Optional[T], val T) T
GetOr is the same as Get, but will return the passed value instead of an error if the Option is None. Another convenience function
func GetOrElse ¶
func GetOrElse[T comparable](opt Optional[T], f func() T) T
GetOrElse calls Get(), but run the passed function and return the result instead of producing an error if the option is None.
func GetOrInsert ¶
func GetOrInsert[T comparable](opt MutableOptional[T], val T) (T, error)
GetOrInsert calls Get, but will call Default on the passed value then return it if the Option is None
func IsSomeAnd ¶
func IsSomeAnd[T comparable](opt Option[T], f func(T) bool) bool
IsSomeAnd returns true if the Option has a value of Some(x) and f(x) == true
func Or ¶
func Or[T comparable, O Optional[T]](left, right O) O
Or returns the first Optional if it contains a value. Otherwise, return the second Optional. This is conceptually similar to left || right. This is a convenience function for situations like merging configs or implementing builder patterns.
func SetDefaultExtraTimeFormats ¶ added in v0.3.1
func SetDefaultExtraTimeFormats(formats []string)
func TransformOr ¶
func TransformOr[T comparable](opt MutableOptional[T], t Transformer[T], backup T) error
TransformOr just calls Transform(), except None values are mapped to backup before being transformed.
Types ¶
type Bool ¶
func (Bool) MarshalText ¶
func (*Bool) True ¶ added in v0.2.1
True returns true iff the value is Some(true). It is a special method exclusive to Bool optionals, and is the same as calling Bool.Match(true).
func (*Bool) UnmarshalText ¶
type Byte ¶ added in v0.3.1
Byte implements LoadableOptional for the byte type.
func (Byte) MarshalText ¶ added in v0.3.1
func (*Byte) UnmarshalText ¶ added in v0.3.1
type Duration ¶ added in v0.3.0
Duration is the optional version of time.Duration. Under the hood, time.Duration is an int64 but we still use an underlying Option[time.Duration] type to get access to all the associated methods.
func NoDuration ¶ added in v0.3.0
func SomeDuration ¶ added in v0.3.0
func (Duration) MarshalJSON ¶ added in v0.3.0
func (Duration) MarshalText ¶ added in v0.3.0
func (*Duration) UnmarshalJSON ¶ added in v0.3.0
UnmarshalJSON implements encoding/json.Unmarshaller interface
func (*Duration) UnmarshalText ¶ added in v0.3.0
type Float64 ¶
func SomeFloat64 ¶
func (Float64) MarshalText ¶
func (*Float64) UnmarshalText ¶
type Int8 ¶
func (Int8) MarshalText ¶
func (*Int8) UnmarshalText ¶
type Int16 ¶
func (Int16) MarshalText ¶
func (*Int16) UnmarshalText ¶
type Int32 ¶
func (Int32) MarshalText ¶
func (*Int32) UnmarshalText ¶
type Int64 ¶
func (Int64) MarshalText ¶
func (*Int64) UnmarshalText ¶
type LoadableOptional ¶
type LoadableOptional[T primatives] interface {
MutableOptional[T]
// Satisfies fmt.Stringer interface
String() string
// Along with String(), implements flag.Value and pflag.Value
Set(string) error
// Along with String() and Set(), implements pflag.Value
Type() string
// Satisfies the encoding.TextMarshaler
MarshalText() (text []byte, err error)
// Satisfies encoding.TextUnmarshaler
UnmarshalText(text []byte) error
}
LoadableOptional is an extension of the Optional interface meant to make it more useful for loading from a variety of sources.
type MutableOptional ¶
type MutableOptional[T comparable] interface { Optional[T] MutableClone() MutableOptional[T] Clear() Default(T) (replaced bool) // Replace updates the current value in the MutableOptional and returns the previous value Replace(T) Optional[T] // Transform only applies the func to the values of Some valued Optionals. Any mapping of None is None. Transform(f Transformer[T]) error // Satisfies encoding.json.UnMarshaler UnmarshalJSON([]byte) error }
MutableOptional is a superset of Optional which allows mutating and transforming the wrapped value.
type Option ¶
type Option[T comparable] struct { // contains filtered or unexported fields }
Option is a generic way to make a field or parameter optional. Instantiating an Optional value through the Some() or None() methods are prefered since it is easier for the reader of your code to see what the expected value of the Option is, but to avoid leaking options across api boundries a FromPointer() method is given. This allows you to accept a parameter as a pointer and immediately convert it into an Option value without having to do the nil check yourself.
While this can be useful on its own, this can also be used to create a specialized option for your use case. See the config package for a comprehensive example of this.
Special care should be taken when creating Options of pointer types. All the same concerns around passing structs with pointer fields apply, since copying the pointer by value will create many copies of the same pointer. There is nothing to stop you from doing this, but I'm not sure what they use case is and it may lead to less understandable code (which is what this library was created to avoid in the first place!)
func FromPointer ¶
func FromPointer[T comparable](p *T) Option[T]
FromPointer creates an option with an inferred type from a pointer. nil pointers are mapped to a None value and non-nil pointers have their value copied into a new option. The pointer itself is not retained and can be modified later without affecting the Option value.
func None ¶
func None[T comparable]() Option[T]
None returns an Option with no value loaded. Note that since there is no value to infer type from, None must be instanciated with the desired type like optional.None[string]().
func Some ¶
func Some[T comparable](value T) Option[T]
Some returns an Option with an inferred type and specified value.
func (*Option[T]) Clear ¶
func (o *Option[T]) Clear()
Clear converts a Some(x) or None type Option into a None value.
func (Option[T]) Clone ¶
Clone creates a copy of the Option by value. This means the new Option may be unwrapped or modified without affecting the old Option. NOTE: the exception to this would be if you create an Option for a pointer type. Because the pointer is copied by value, it will still refer to the same value.
func (*Option[T]) Default ¶ added in v0.2.0
Default is a special case of replace where the value of the option is only changed if the current value is None.
func (Option[T]) Get ¶
Get returns the current wrapped value of a Some value Option and an ok value indicating if the Option was Some or None. Note that the wrapped value returned if ok == false if undefined so ALWAYS CHECK.
func (Option[T]) MarshalJSON ¶
MarshalJSON implements the encoding.json.Marshaler interface. None values are marshaled to json null, while Some values are passed into json.Marshal directly.
func (Option[T]) MustGet ¶ added in v0.2.0
func (o Option[T]) MustGet() T
MustGet is exactly like get, but panics for None instead of returning an error. This makes for potentially more readable code if paired with Option.IsSome or in a template and gives an exciting sense of danger.
func (Option[T]) MutableClone ¶
func (o Option[T]) MutableClone() MutableOptional[T]
MutableClone creates a copy of the Option by value the same as Clone. The only differnce is that the returned type is a pointer cast as a MutableOptional so that the returned value can be further modified.
func (*Option[T]) Replace ¶
Replace converts a Some(x) or None type Option into a Some(value) value.
func (*Option[T]) Transform ¶
func (o *Option[T]) Transform(t Transformer[T]) error
Transform applies function f(T) to the inner value of the Option. If the Option is None, then the Option will remain None.
func (*Option[T]) UnmarshalJSON ¶
UnmarshalJSON implements the encoding.json.Unmarshaller interface. Json nulls are unmarshaled into None values, while any other value is attempted to unmarshal as normal. Any error encountered is returned without modification. There are some protections included to make sure that unmarshaling an uninitialized Option[T] does not break the Option invariants.
type Optional ¶
type Optional[T comparable] interface { IsSome() bool IsNone() bool Clone() Optional[T] Get() (val T, ok bool) MustGet() T Match(T) bool // Satisfies encoding.json.Marshaler MarshalJSON() ([]byte, error) }
Optional defines the functionality needed to provide good ergonimics around optional fields and values. In general, code should not declare variables or parameters as Optionals and instead prefer using concrete types like Option. This interface is meant to ensure compatablility between different concrete option types and for the rare cases where the abstraction is actually necessary.
type OptionalError ¶
type OptionalError struct {
// contains filtered or unexported fields
}
func (OptionalError) Error ¶
func (e OptionalError) Error() string
type Secret ¶ added in v0.2.2
type Secret struct {
Str
}
Secret wraps another Optional which may hold sensitive information. The value may still be marshaled into messages, but when printing to the console or logs it should be redacted.
TODO: We should make this automatically encrypt secrets at rest.
func MakeSecret ¶ added in v0.2.2
MakeSecret creates a Secret from a pointer to Str optional then clears the original. This is to ensure the original optional is never logged, thereby leaking the secret.
func SomeSecret ¶ added in v0.2.2
func (Secret) Format ¶ added in v0.2.2
Format ALWAYS ALWAYS redact secrets no matter what formatting verb or flag is set
func (Secret) LogValue ¶ added in v0.2.2
LogValue even redacts secrets when logging. What a surprise!
type StorableOptional ¶ added in v0.3.1
type StorableOptional[T comparable] interface { MutableOptional[T] // Implements database/sql.Scanner interface Scan(src any) error // Implements the database/sqlc.Valuer interface Value() (any, error) }
StorableOptional is an extension of the MutableOptional interface that allows golang's database/sql package to correctly store and retrieve values.
type Str ¶
func (Str) MarshalText ¶
func (*Str) UnmarshalText ¶
type Time ¶
type Time struct {
Option[time.Time]
StringFormat string
DataFormat string
// contains filtered or unexported fields
}
func (Time) MarshalJSON ¶
func (Time) MarshalText ¶
func (*Time) UnmarshalJSON ¶
UnmarshalJSON implements encoding/json.Unmarshaller interface
func (*Time) UnmarshalText ¶
func (Time) WithFormats ¶
type Transformer ¶
type Transformer[T comparable] func(T) (T, error)