From bef5a9bd2d0e004e6502a883f1c5fd83fa5fb72e Mon Sep 17 00:00:00 2001 From: tdakkota Date: Mon, 30 May 2022 15:54:48 +0300 Subject: [PATCH 1/2] chore: bump Go version requirement to 1.18 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a4e3702..e421c82 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/go-faster/errors -go 1.17 +go 1.18 From b53f5debb25e69505dcb4dd8c21b6de96fc76818 Mon Sep 17 00:00:00 2001 From: tdakkota Date: Mon, 30 May 2022 15:55:09 +0300 Subject: [PATCH 2/2] feat: add Into and Must generic helpers --- example_Into_test.go | 20 ++++++++++++++++++++ example_Must_test.go | 16 ++++++++++++++++ into.go | 9 +++++++++ must.go | 10 ++++++++++ must_test.go | 24 ++++++++++++++++++++++++ 5 files changed, 79 insertions(+) create mode 100644 example_Into_test.go create mode 100644 example_Must_test.go create mode 100644 into.go create mode 100644 must.go create mode 100644 must_test.go diff --git a/example_Into_test.go b/example_Into_test.go new file mode 100644 index 0000000..e70ed60 --- /dev/null +++ b/example_Into_test.go @@ -0,0 +1,20 @@ +package errors_test + +import ( + "fmt" + "os" + + "github.com/go-faster/errors" +) + +func ExampleInto() { + _, err := os.Open("non-existing") + if err != nil { + if pathError, ok := errors.Into[*os.PathError](err); ok { + fmt.Println("Failed at path:", pathError.Path) + } + } + + // Output: + // Failed at path: non-existing +} diff --git a/example_Must_test.go b/example_Must_test.go new file mode 100644 index 0000000..286c238 --- /dev/null +++ b/example_Must_test.go @@ -0,0 +1,16 @@ +package errors_test + +import ( + "fmt" + "net/url" + + "github.com/go-faster/errors" +) + +func ExampleMust() { + r := errors.Must(url.Parse(`https://google.com`)) + fmt.Println(r.String()) + + // Output: + // https://google.com +} diff --git a/into.go b/into.go new file mode 100644 index 0000000..7a867d6 --- /dev/null +++ b/into.go @@ -0,0 +1,9 @@ +package errors + +// Into finds the first error in err's chain that matches target type T, and if so, returns it. +// +// Into is type-safe alternative to As. +func Into[T error](err error) (val T, ok bool) { + ok = As(err, &val) + return val, ok +} diff --git a/must.go b/must.go new file mode 100644 index 0000000..e9c83c3 --- /dev/null +++ b/must.go @@ -0,0 +1,10 @@ +package errors + +// Must is a generic helper, like template.Must, that wraps a call to a function returning (T, error) +// and panics if the error is non-nil. +func Must[T any](val T, err error) T { + if err != nil { + panic(err) + } + return val +} diff --git a/must_test.go b/must_test.go new file mode 100644 index 0000000..b3a579b --- /dev/null +++ b/must_test.go @@ -0,0 +1,24 @@ +package errors + +import ( + "testing" +) + +func TestMust(t *testing.T) { + if got := Must(10, nil); got != 10 { + t.Fatalf("Expected %+v, got %+v", 10, got) + } + + panics := func() (r bool) { + defer func() { + if recover() != nil { + r = true + } + }() + Must(10, New("test error")) + return r + }() + if !panics { + t.Fatal("Panic expected") + } +}