Add Result type (#16)

* 👷 adding test and push coverage

* ⬆️ use official Go 1.18 image

*  result interface

* delete commented code

Co-authored-by: Ruidy <rnemausat@newstore.com>
This commit is contained in:
Ruidy 2022-03-18 13:32:41 -04:00 committed by GitHub
parent 3bfe1aca18
commit e156992382
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 0 deletions

49
result.go Normal file
View file

@ -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}
}

41
result_test.go Normal file
View file

@ -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"))
}