From fb7490a67e2f8704c4a07dc9ecbbc51b26a50728 Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:20:39 +0100 Subject: [PATCH] feat: add MustConvert This function calls Convert and panics if there is an error --- conversion.go | 9 +++++++ conversion_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/conversion.go b/conversion.go index 4c17095..3bf4e41 100644 --- a/conversion.go +++ b/conversion.go @@ -61,6 +61,15 @@ func Convert[NumOut Number](orig any) (converted NumOut, err error) { } } +// MustConvert calls [Convert] to convert the value to the desired type, and panics if the conversion fails. +func MustConvert[NumOut Number](orig any) NumOut { + converted, err := Convert[NumOut](orig) + if err != nil { + panic(err) + } + return converted +} + func convertFromNumber[NumOut Number, NumIn Number](orig NumIn) (converted NumOut, err error) { converted = NumOut(orig) diff --git a/conversion_test.go b/conversion_test.go index 9232dc8..17a670a 100644 --- a/conversion_test.go +++ b/conversion_test.go @@ -8,6 +8,7 @@ package safecast_test // This is why it needs to be tested in an architecture dependent way. import ( + "errors" "fmt" "math" "testing" @@ -1929,3 +1930,64 @@ func TestConvert(t *testing.T) { } }) } + +func TestMustConvert(t *testing.T) { + // [TestConvert] tested all the cases + // here we are simply checking that the function panic on errors + + t.Run("panic on error", func(t *testing.T) { + for name, input := range map[string]any{ + "nil": nil, + "negative": -1, + "overflow": math.MaxInt, + "string": "cats", + } { + t.Run(name, func(t *testing.T) { + // configure validate there is no panic + defer func(t *testing.T) { + t.Helper() + + r := recover() + if r == nil { + t.Fatal("did not panic") + } + + err, ok := r.(error) + if !ok { + t.Fatalf("panic value is not an error: %v", r) + } + + if !errors.Is(err, safecast.ErrConversionIssue) { + t.Fatalf("panic with unexpected error: %v", err) + } + }(t) + + safecast.MustConvert[uint8](input) + }) + } + }) + + t.Run("no panic", func(t *testing.T) { + for name, input := range map[string]any{ + "number": 42, + "string": "42", + "octal": "0o52", + "float": 42.0, + } { + t.Run(name, func(t *testing.T) { + // configure a helper to validate there is no panic + defer func(t *testing.T) { + t.Helper() + + err := recover() + if err != nil { + t.Fatalf("panic with %v", err) + } + }(t) + + converted := safecast.MustConvert[int](input) + assertEqual(t, 42, converted) + }) + } + }) +}