Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions result.go
Original file line number Diff line number Diff line change
@@ -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 changes: 41 additions & 0 deletions result_test.go
Original file line number Diff line number Diff line change
@@ -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"))
}