diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8c2407e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" # Location of package manifests + schedule: + interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/.github/workflows/include.yml b/.github/workflows/include.yml new file mode 100644 index 0000000..3dfb133 --- /dev/null +++ b/.github/workflows/include.yml @@ -0,0 +1,16 @@ +# Same as full workflow (eg from fortio/multicurl) but without the goreleaser step +name: "Shared library fortio workflows" + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + call-gochecks: + uses: fortio/workflows/.github/workflows/gochecks.yml@main + call-codecov: + uses: fortio/workflows/.github/workflows/codecov.yml@main + call-codeql: + uses: fortio/workflows/.github/workflows/codeql-analysis.yml@main diff --git a/README.md b/README.md index 9ddb2f5..23d0194 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ [![Go Report Card](https://goreportcard.com/badge/fortio.org/safecast)](https://goreportcard.com/report/fortio.org/safecast) [![GoDoc](https://godoc.org/fortio.org/safecast?status.svg)](https://pkg.go.dev/fortio.org/safecast) +[![codecov](https://codecov.io/gh/fortio/safecast/branch/main/graph/badge.svg)](https://codecov.io/gh/fortio/safecast) Avoid accidental overflow of numbers during go type conversions (e.g instead of `shorter := bigger.(int8)` type conversions use `shorter := safecast.MustConvert[int8](bigger)`. Safecast allows you to safely convert between numeric types in Go and return errors (or panic when using the `Must*` variants) when the cast would result in a loss of precision, range or sign. See https://pkg.go.dev/fortio.org/safecast for docs and example. +This is usable from any go with generics (1.18 or later) though our CI uses the latest go. Idea: @ccoVeille see https://github.com/ccoVeille/go-safecast for an different style API and implementation. diff --git a/go.mod b/go.mod index 5424ea9..4674570 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module fortio.org/safecast -go 1.20 +go 1.20 // Really 1.18 or higher, just need generics. do use a supported version of go. diff --git a/safecast_test.go b/safecast_test.go index 52baba7..8758402 100644 --- a/safecast_test.go +++ b/safecast_test.go @@ -7,6 +7,8 @@ import ( "fortio.org/safecast" ) +// TODO: steal the tests from https://github.com/ccoVeille/go-safecast + func TestConvert(t *testing.T) { var inp uint32 = 42 out, err := safecast.Convert[int8](inp) @@ -70,9 +72,13 @@ func TestConvert(t *testing.T) { if ub != 255 { t.Errorf("unexpected value: %v", ub) } + ub = safecast.MustConvert[uint8](int64(255)) // shouldn't panic + if ub != 255 { + t.Errorf("unexpected value: %v", ub) + } } -func TestPanic(t *testing.T) { +func TestPanicMustRound(t *testing.T) { defer func() { r := recover() if r == nil { @@ -87,6 +93,36 @@ func TestPanic(t *testing.T) { safecast.MustRound[uint8](float32(255.5)) } +func TestPanicMustTruncate(t *testing.T) { + defer func() { + r := recover() + if r == nil { + t.Errorf("expected panic") + } else { + expected := "safecast: out of range for -1.5 (float32) to uint8" + if r != expected { + t.Errorf("unexpected panic: %q wanted %q", r, expected) + } + } + }() + safecast.MustTruncate[uint8](float32(-1.5)) +} + +func TestPanicMustConvert(t *testing.T) { + defer func() { + r := recover() + if r == nil { + t.Errorf("expected panic") + } else { + expected := "safecast: out of range for 256 (int) to uint8" + if r != expected { + t.Errorf("unexpected panic: %q wanted %q", r, expected) + } + } + }() + safecast.MustConvert[uint8](256) +} + func Example() { var in int16 = 256 // will error out