github.com/enetx/g@v1.0.80/result.go (about) 1 package g 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "runtime" 8 ) 9 10 // Ok returns a new Result[T] containing the given value. 11 func Ok[T any](value T) Result[T] { return Result[T]{value: &value, err: nil} } 12 13 // Err returns a new Result[T] containing the given error. 14 func Err[T any](err error) Result[T] { return Result[T]{value: nil, err: err} } 15 16 // ResultOf returns a new Result[T] based on the provided value and error. 17 // If err is not nil, it returns an Result containing the error. 18 // Otherwise, it returns an Result containing the value. 19 func ResultOf[T any](value T, err error) Result[T] { 20 if err != nil { 21 return Err[T](err) 22 } 23 24 return Ok(value) 25 } 26 27 // ResultMap applies the given function to the value inside the Result, producing a new Result with the transformed value. 28 // If the input Result contains a value, the provided function is applied to it. 29 // If the input Result contains an error, the output Result will also contain the same error. 30 // Parameters: 31 // - r: The input Result to map over. 32 // - fn: The function that returns a Result to apply to the value inside the Result. 33 // 34 // Returns: 35 // 36 // A new Result with the transformed value, or the same error if the input Result contained an error. 37 func ResultMap[T, U any](r Result[T], fn func(T) Result[U]) Result[U] { 38 if r.IsErr() { 39 return Err[U](r.Err()) 40 } 41 42 return fn(r.Ok()) 43 } 44 45 // ResultOfMap applies the given function to the value inside the Result, producing a new Result with the transformed value. 46 // If the input Result contains a value, the provided function is applied to it. 47 // If the input Result contains an error, the output Result will also contain the same error. 48 // Parameters: 49 // - r: The input Result to map over. 50 // - fn: The function that returns a tuple (U, error) to apply to the value inside the Result. 51 // 52 // Returns: 53 // 54 // A new Result with the transformed value, or the same error if the input Result contained an error. 55 func ResultOfMap[T, U any](r Result[T], fn func(T) (U, error)) Result[U] { 56 if r.IsErr() { 57 return Err[U](r.Err()) 58 } 59 60 return ResultOf(fn(r.Ok())) 61 } 62 63 // Ok returns the value held in the Result. 64 func (r Result[T]) Ok() T { return *r.value } 65 66 // Err returns the error held in the Result. 67 func (r Result[T]) Err() error { return r.err } 68 69 // IsOk returns true if the Result contains a value (no error). 70 func (r Result[T]) IsOk() bool { return r.err == nil } 71 72 // IsErr returns true if the Result contains an error. 73 func (r Result[T]) IsErr() bool { return r.err != nil } 74 75 // Result returns the value held in the Result and its error. 76 func (r Result[T]) Result() (T, error) { 77 if r.IsErr() { 78 return *new(T), r.Err() 79 } 80 81 return r.Ok(), nil 82 } 83 84 // Unwrap returns the value held in the Result. If the Result contains an error, it panics. 85 func (r Result[T]) Unwrap() T { 86 if r.IsErr() { 87 if pc, file, line, ok := runtime.Caller(1); ok { 88 out := fmt.Sprintf("[%s:%d] [%s] %v", filepath.Base(file), line, runtime.FuncForPC(pc).Name(), r.err) 89 fmt.Fprintln(os.Stderr, out) 90 } 91 92 panic(r.err) 93 } 94 95 return r.Ok() 96 } 97 98 // UnwrapOr returns the value held in the Result. If the Result contains an error, it returns the provided default value. 99 func (r Result[T]) UnwrapOr(value T) T { 100 if r.IsErr() { 101 return value 102 } 103 104 return r.Ok() 105 } 106 107 // UnwrapOrDefault returns the value held in the Result. If the Result contains an error, 108 // it returns the default value for type T. Otherwise, it returns the value held in the Result. 109 func (r Result[T]) UnwrapOrDefault() T { 110 if r.IsErr() { 111 return *new(T) 112 } 113 114 return r.Ok() 115 } 116 117 // Expect returns the value held in the Result. If the Result contains an error, it panics with the provided message. 118 func (r Result[T]) Expect(msg string) T { 119 if r.IsErr() { 120 out := fmt.Sprintf("%s: %v", msg, r.err) 121 fmt.Fprintln(os.Stderr, out) 122 panic(out) 123 } 124 125 return r.Ok() 126 } 127 128 // Then applies the function fn to the value inside the Result and returns a new Result. 129 // If the Result contains an error, it returns the same Result without applying fn. 130 func (r Result[T]) Then(fn func(T) Result[T]) Result[T] { 131 if r.IsErr() { 132 return r 133 } 134 135 return fn(r.Ok()) 136 } 137 138 // ThenOf applies the function fn to the value inside the Result, expecting 139 // fn to return a tuple (T, error), and returns a new Result based on the 140 // returned tuple. If the Result contains an error, it returns the same Result 141 // without applying fn. 142 func (r Result[T]) ThenOf(fn func(T) (T, error)) Result[T] { 143 if r.IsErr() { 144 return r 145 } 146 147 return ResultOf(fn(r.Ok())) 148 } 149 150 // Option converts a Result into an Option. 151 // If the Result contains an error, it returns None. 152 // If the Result contains a value, it returns Some with the value. 153 // Parameters: 154 // - r: The input Result to convert into an Option. 155 // 156 // Returns: 157 // 158 // An Option representing the value of the Result, if any. 159 func (r Result[T]) Option() Option[T] { 160 if r.IsErr() { 161 return None[T]() 162 } 163 164 return Some(r.Ok()) 165 } 166 167 func (r Result[T]) String() string { 168 if r.IsOk() { 169 return fmt.Sprintf("Ok(%v)", r.Ok()) 170 } 171 172 return fmt.Sprintf("Err(%s)", r.Err().Error()) 173 }