diff --git a/typeutils/optional.go b/typeutils/optional.go index d65b3da..782cbb1 100644 --- a/typeutils/optional.go +++ b/typeutils/optional.go @@ -1,5 +1,7 @@ package typeutils +import "github.com/lbatuska/goutils/assert" + // CTORS BEGIN func Some[T any](value T) Optional[T] { return Optional[T]{value, true} @@ -16,44 +18,68 @@ func None_t[T any](T) Optional[T] { // CTORS END -func (opt Optional[T]) IsSome() bool { return opt.present } -func (opt Optional[T]) IsNone() bool { return !opt.present } +func (opt *Optional[T]) IsSome() bool { + if opt == nil { + return false + } + return opt.present +} -func (opt Optional[T]) HasValue() bool { return opt.IsSome() } +func (opt *Optional[T]) IsNone() bool { + if opt == nil { + return true + } + return !opt.present +} + +func (opt *Optional[T]) HasValue() bool { + if opt == nil { + return false + } + return opt.IsSome() +} // UNWRAPPABLE INTERFACE BEGIN -func (opt Optional[T]) Expect(msg string) T { +func (opt *Optional[T]) Expect(msg string) T { + assert.NotNil(opt) if opt.present { return opt.value } panic(msg) } -func (opt Optional[T]) Unwrap() T { +func (opt *Optional[T]) Unwrap() T { + assert.NotNil(opt) if opt.present { return opt.value } panic("Tried unwrapping an Optional that did not have a value!") } -func (opt Optional[T]) UnwrapOr(val T) T { - if opt.present { - return opt.value +func (opt *Optional[T]) UnwrapOr(val T) T { + if opt != nil { + if opt.present { + return opt.value + } } return val } -func (opt Optional[T]) UnwrapOrDefault() T { - if opt.present { - return opt.value +func (opt *Optional[T]) UnwrapOrDefault() T { + if opt != nil { + if opt.present { + return opt.value + } } var res T return res } -func (opt Optional[T]) UnwrapOrElse(f func() T) T { - if opt.present { - return opt.value +func (opt *Optional[T]) UnwrapOrElse(f func() T) T { + if opt != nil { + if opt.present { + return opt.value + } } return f() } @@ -61,17 +87,22 @@ func (opt Optional[T]) UnwrapOrElse(f func() T) T { // UNWRAPPABLE INTERFACE END // transforms Some(v) to Ok(v), and None to Err(err) -func (opt Optional[T]) OkOr(err error) Result[T] { - if opt.present { - return Ok(opt.value) +func (opt *Optional[T]) OkOr(err error) Result[T] { + if opt != nil { + if opt.present { + return Ok(opt.value) + } } + return Err[T](err) } // transforms Some(v) to Ok(v), and None to a value of Err using the provided function -func (opt Optional[T]) OkOrElse(f func() error) Result[T] { - if opt.present { - return Ok(opt.value) +func (opt *Optional[T]) OkOrElse(f func() error) Result[T] { + if opt != nil { + if opt.present { + return Ok(opt.value) + } } return Err[T](f()) } diff --git a/typeutils/result.go b/typeutils/result.go index 5bf9dec..3af51d9 100644 --- a/typeutils/result.go +++ b/typeutils/result.go @@ -1,5 +1,11 @@ package typeutils +import ( + "errors" + + "github.com/lbatuska/goutils/assert" +) + // CTORS BEGIN func Ok[T any](value T) Result[T] { return Result[T]{value: value, err: nil} @@ -15,44 +21,68 @@ func Err_t[T any](err error, x T) Result[T] { // CTORS END -func (res Result[T]) IsOk() bool { return res.err == nil } -func (res Result[T]) IsErr() bool { return res.err != nil } +func (res *Result[T]) IsOk() bool { + if res == nil { + return false + } + return res.err == nil +} -func (res Result[T]) HasValue() bool { return res.IsOk() } +func (res *Result[T]) IsErr() bool { + if res == nil { + return true + } + return res.err != nil +} + +func (res *Result[T]) HasValue() bool { + if res == nil { + return false + } + return res.IsOk() +} // UNWRAPPABLE INTERFACE -func (res Result[T]) Expect(msg string) T { +func (res *Result[T]) Expect(msg string) T { + assert.NotNil(res) if res.err == nil { return res.value } panic(msg) } -func (res Result[T]) Unwrap() T { +func (res *Result[T]) Unwrap() T { + assert.NotNil(res) if res.err == nil { return res.value } panic("Tried unwrapping a Result that had an error value!") } -func (res Result[T]) UnwrapOr(val T) T { - if res.err == nil { - return res.value +func (res *Result[T]) UnwrapOr(val T) T { + if res != nil { + if res.err == nil { + return res.value + } } return val } -func (res Result[T]) UnwrapOrDefault() T { - if res.err == nil { - return res.value +func (res *Result[T]) UnwrapOrDefault() T { + if res != nil { + if res.err == nil { + return res.value + } } var ret T return ret } -func (res Result[T]) UnwrapOrElse(f func() T) T { - if res.err == nil { - return res.value +func (res *Result[T]) UnwrapOrElse(f func() T) T { + if res != nil { + if res.err == nil { + return res.value + } } return f() } @@ -60,7 +90,11 @@ func (res Result[T]) UnwrapOrElse(f func() T) T { // UNWRAPPABLE INTERFACE // This function panic on Ok instead of Err -func (res Result[T]) ExpectErr(msg string) error { +func (res *Result[T]) ExpectErr(msg string) error { + if res == nil { + return errors.New("ExpectErr was called on a nil Result.") + } + if res.err != nil { return res.err } @@ -68,7 +102,10 @@ func (res Result[T]) ExpectErr(msg string) error { } // This function panic on Ok instead of Err -func (res Result[T]) UnwrapErr() error { +func (res *Result[T]) UnwrapErr() error { + if res == nil { + return errors.New("UnwrapErr was called on a nil Result.") + } if res.err != nil { return res.err } @@ -76,15 +113,22 @@ func (res Result[T]) UnwrapErr() error { } // transforms Result into Option, mapping Ok(v) to Some(v) and Err(e) to None -func (res Result[T]) Ok() Optional[T] { - if res.err == nil { - return Optional[T]{value: res.value, present: true} +func (res *Result[T]) Ok() Optional[T] { + if res != nil { + if res.err == nil { + return Optional[T]{value: res.value, present: true} + } } return Optional[T]{present: false} } // transforms Result into Option, mapping Err(e) to Some(e) and Ok(v) to None -func (res Result[T]) Err() Optional[error] { +func (res *Result[T]) Err() Optional[error] { + if res == nil { + return Optional[error]{ + value: errors.New("Err was called on a nil Result."), present: true, + } + } if res.err != nil { return Optional[error]{value: res.err, present: true} }