diff --git a/result.go b/result.go new file mode 100644 index 0000000..d6463f4 --- /dev/null +++ b/result.go @@ -0,0 +1,49 @@ +package underscore + +// Result represent the outcome of an operation where failure is possible +type Result[T any] interface { + isResult() //to seal the Result interface + ToValue() (*T, error) + IsSuccess() bool +} + +// Ok is the Result that represents success. +type Ok[T any] struct { + Value *T +} + +func (Ok[T]) isResult() {} + +func (o Ok[T]) ToValue() (*T, error) { + return o.Value, nil +} + +func (o Ok[T]) IsSuccess() bool { + return true +} + +// Err is the Result that represents failure. It implements the error interface +type Err[T any] struct{ Err error } + +func (e Err[T]) ToValue() (*T, error) { + return nil, e.Err +} + +func (e Err[T]) IsSuccess() bool { + return false +} + +func (Err[T]) isResult() {} + +func (e Err[T]) Error() string { + return e.Err.Error() +} + +func ToResult[T any](value *T, err error) Result[T] { + if err != nil { + return Err[T]{ + Err: err, + } + } + return Ok[T]{Value: value} +} diff --git a/result_test.go b/result_test.go new file mode 100644 index 0000000..75c9398 --- /dev/null +++ b/result_test.go @@ -0,0 +1,41 @@ +package underscore_test + +import ( + "errors" + "testing" + + u "github.com/rjNemo/underscore" + "github.com/stretchr/testify/assert" +) + +func TestSuccess(t *testing.T) { + res := isAnswerToLife(42) + assert.True(t, res.IsSuccess()) +} + +func TestFailure(t *testing.T) { + res := isAnswerToLife(13) + assert.False(t, res.IsSuccess()) +} + +func TestIsOK(t *testing.T) { + res, err := isAnswerToLife(42).ToValue() + assert.NoError(t, err) + assert.Equal(t, "You get it", *res) +} + +func TestIsError(t *testing.T) { + life := isAnswerToLife(13) + res, err := life.ToValue() + assert.Error(t, err) + assert.Equal(t, "nope", life.(u.Err[string]).Error()) + assert.Nil(t, res) +} + +func isAnswerToLife(num int) u.Result[string] { + if num == 42 { + res := "You get it" + return u.ToResult(&res, nil) + } + return u.ToResult[string](nil, errors.New("nope")) +}