github.com/mitranim/gg@v0.1.17/maybe.go (about)

     1  package gg
     2  
     3  import "encoding/json"
     4  
     5  // Shortcut for creating a `Maybe` with the given value.
     6  func MaybeVal[A any](val A) Maybe[A] { return Maybe[A]{val, nil} }
     7  
     8  // Shortcut for creating a `Maybe` with the given error.
     9  func MaybeErr[A any](err error) Maybe[A] { return Maybe[A]{Zero[A](), err} }
    10  
    11  /*
    12  Contains a value or an error. The JSON tags "value" and "error" are chosen due
    13  to their existing popularity in HTTP API.
    14  */
    15  type Maybe[A any] struct {
    16  	Val A     `json:"value,omitempty"`
    17  	Err error `json:"error,omitempty"`
    18  }
    19  
    20  /*
    21  Asserts that the error is nil, returning the resulting value. If the error is
    22  non-nil, panics via `Try`, idempotently adding a stack trace to the error.
    23  */
    24  func (self Maybe[A]) Ok() A {
    25  	Try(self.Err)
    26  	return self.Val
    27  }
    28  
    29  // Implement `Getter`, returning the underlying value as-is.
    30  func (self Maybe[A]) Get() A { return self.Val }
    31  
    32  // Implement `Setter`. Sets the underlying value and clears the error.
    33  func (self *Maybe[A]) Set(val A) {
    34  	self.Val = val
    35  	self.Err = nil
    36  }
    37  
    38  // Returns the underlying error as-is.
    39  func (self Maybe[_]) GetErr() error { return self.Err }
    40  
    41  // Sets the error. If the error is non-nil, clears the value.
    42  func (self *Maybe[A]) SetErr(err error) {
    43  	if err != nil {
    44  		self.Val = Zero[A]()
    45  	}
    46  	self.Err = err
    47  }
    48  
    49  // True if error is non-nil.
    50  func (self Maybe[_]) HasErr() bool { return self.Err != nil }
    51  
    52  /*
    53  Implement `json.Marshaler`. If the underlying error is non-nil, returns that
    54  error. Otherwise uses `json.Marshal` to encode the underlying value.
    55  */
    56  func (self Maybe[_]) MarshalJSON() ([]byte, error) {
    57  	if self.Err != nil {
    58  		return nil, self.Err
    59  	}
    60  	return json.Marshal(self.Val)
    61  }
    62  
    63  // Implement `json.Unmarshaler`, decoding into the underlying value.
    64  func (self *Maybe[_]) UnmarshalJSON(src []byte) error {
    65  	self.Err = nil
    66  	return json.Unmarshal(src, &self.Val)
    67  }