github.com/enetx/g@v1.0.80/option.go (about)

     1  package g
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  )
    10  
    11  // Some creates an Option containing a non-nil value.
    12  func Some[T any](value T) Option[T] { return Option[T]{&value} }
    13  
    14  // None creates an Option containing a nil value.
    15  func None[T any]() Option[T] { return Option[T]{nil} }
    16  
    17  // OptionMap applies the given function to the value inside the Option, producing a new Option with the transformed value.
    18  // If the input Option is None, the output Option will also be None.
    19  // Parameters:
    20  //   - o: The input Option to map over.
    21  //   - fn: The function to apply to the value inside the Option.
    22  //
    23  // Returns:
    24  //
    25  //	A new Option with the transformed value.
    26  func OptionMap[T, U any](o Option[T], fn func(T) Option[U]) Option[U] {
    27  	if o.IsNone() {
    28  		return None[U]()
    29  	}
    30  
    31  	return fn(o.Some())
    32  }
    33  
    34  // Some returns the value held in the Option.
    35  func (o Option[T]) Some() T { return *o.value }
    36  
    37  // IsSome returns true if the Option contains a non-nil value.
    38  func (o Option[T]) IsSome() bool { return o.value != nil }
    39  
    40  // IsNone returns true if the Option contains a nil value.
    41  func (o Option[T]) IsNone() bool { return o.value == nil }
    42  
    43  // Unwrap returns the value held in the Option. If the Option contains a nil value, it panics.
    44  func (o Option[T]) Unwrap() T {
    45  	if o.IsNone() {
    46  		err := errors.New("can't unwrap none value")
    47  		if pc, file, line, ok := runtime.Caller(1); ok {
    48  			out := fmt.Sprintf("[%s:%d] [%s] %v", filepath.Base(file), line, runtime.FuncForPC(pc).Name(), err)
    49  			fmt.Fprintln(os.Stderr, out)
    50  		}
    51  
    52  		panic(err)
    53  	}
    54  
    55  	return o.Some()
    56  }
    57  
    58  // UnwrapOr returns the value held in the Option. If the Option contains a nil value, it returns the provided default value.
    59  func (o Option[T]) UnwrapOr(value T) T {
    60  	if o.IsNone() {
    61  		return value
    62  	}
    63  
    64  	return o.Some()
    65  }
    66  
    67  // UnwrapOrDefault returns the value held in the Option. If the Option contains a value,
    68  // it returns the value. If the Option is None, it returns the default value for type T.
    69  func (o Option[T]) UnwrapOrDefault() T {
    70  	if o.IsNone() {
    71  		return *new(T)
    72  	}
    73  
    74  	return o.Some()
    75  }
    76  
    77  // Expect returns the value held in the Option. If the Option contains a nil value, it panics with the provided message.
    78  func (o Option[T]) Expect(msg string) T {
    79  	if o.IsNone() {
    80  		panic(msg)
    81  	}
    82  
    83  	return o.Some()
    84  }
    85  
    86  // Then applies the function fn to the value inside the Option and returns a new Option.
    87  // If the Option is None, it returns the same Option without applying fn.
    88  func (o Option[T]) Then(fn func(T) Option[T]) Option[T] {
    89  	if o.IsNone() {
    90  		return o
    91  	}
    92  
    93  	return fn(o.Some())
    94  }
    95  
    96  func (o Option[T]) String() string {
    97  	if o.IsSome() {
    98  		return fmt.Sprintf("Some(%v)", o.Some())
    99  	}
   100  
   101  	return "None"
   102  }