github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/option/option.go (about)

     1  package option
     2  
     3  // Type Option represents an optional value:
     4  // every Option is either Some and contains a value,
     5  // or None, and does not.
     6  // - Initial values
     7  // - Return values for functions that are not defined over their entire input range (partial functions)
     8  // - Return value for otherwise reporting simple errors, where None is returned on error
     9  // - Optional struct fields
    10  // - Struct fields that can be loaned or "taken"
    11  // - Optional function arguments
    12  // - Nullable pointers
    13  // - Swapping things out of difficult situations
    14  //
    15  // Options are commonly paired with pattern matching to query the presence of a value and take action, always accounting for the None case.
    16  type Option struct {
    17  	data interface{}
    18  	v    bool
    19  }
    20  
    21  // Some value T
    22  func Some(s interface{}) Option { return Option{data: s, v: true} }
    23  
    24  // No value
    25  func None() Option { return Option{} }
    26  
    27  func (o Option) IsSome() bool { return o.v }
    28  
    29  func (o Option) IsNone() bool { return !o.IsSome() }
    30  
    31  // Returns None if the option is None, otherwise returns optb.
    32  func (o Option) And(optb Option) Option {
    33  	if o.IsNone() {
    34  		return None()
    35  	}
    36  	return optb
    37  }
    38  
    39  func (o Option) AndThen(fn func(interface{}) Option) Option {
    40  	if o.IsNone() {
    41  		return None()
    42  	}
    43  	return fn(o.data)
    44  }
    45  
    46  // Returns the option if it contains a value, otherwise returns optb.
    47  func (o Option) Or(optb Option) Option {
    48  	if o.IsNone() {
    49  		return optb
    50  	}
    51  	return o
    52  }
    53  
    54  func (o Option) OrElse(fn func() Option) Option {
    55  	if o.IsNone() {
    56  		return fn()
    57  	}
    58  	return o
    59  }
    60  
    61  func (o Option) Map(fn func(interface{}) interface{}) Option {
    62  	if o.IsNone() {
    63  		return None()
    64  	}
    65  	return Some(fn(o.data))
    66  }
    67  
    68  // Applies a function to the contained value (if any), or returns the provided default (if not).
    69  func (o Option) MapOr(defValue interface{}, fn func(interface{}) interface{}) Option {
    70  	if o.IsSome() {
    71  		return Some(fn(o.data))
    72  	}
    73  	return Some(defValue)
    74  }
    75  
    76  // Returns the contained Some value, consuming the self value.
    77  //
    78  // Because this function may panic, its use is generally discouraged.
    79  // Instead, prefer to use pattern matching and handle the None case explicitly,
    80  // or call `unwrap_or`, `unwrap_or_else`.
    81  func (o Option) Unwrap() interface{} {
    82  	if o.IsNone() {
    83  		panic("unwrap Option None")
    84  	}
    85  	return o.data
    86  }
    87  
    88  func (o Option) UnwrapOr(v interface{}) interface{} {
    89  	if o.IsNone() {
    90  		return v
    91  	}
    92  	return o.data
    93  }
    94  
    95  func (o Option) UnwrapOrElse(fn func() interface{}) interface{} {
    96  	if o.IsNone() {
    97  		return fn()
    98  	}
    99  	return o.data
   100  }