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 }