Documentation
¶
Overview ¶
Package safecast solves the type conversion issues in Go
In Go, integer type conversion can lead to unexpected behavior and errors if not handled carefully. Issues can happen when converting between signed and unsigned integers, or when converting to a smaller integer type.
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
var a int64
a = 42
b, err := safecast.Convert[int16](a) // everything is fine because 42 fits in int16
if err != nil {
fmt.Println(err)
}
fmt.Println(b)
a = 255 + 1
_, err = safecast.Convert[uint8](a) // 256 is greater than uint8 maximum value
if err != nil {
fmt.Println(err)
}
a = -1
_, err = safecast.Convert[uint64](a) // -1 cannot fit in uint64
if err != nil {
fmt.Println(err)
}
str := "\x99" // ASCII code 153 for Trademark symbol
e := str[0]
_, err = safecast.Convert[int8](e)
if err != nil {
fmt.Println(err)
}
}
Output: 42 conversion issue: 256 (int64) is greater than 255 (uint8): maximum value for this type exceeded conversion issue: -1 (int64) is less than 0 (uint64): minimum value for this type exceeded conversion issue: 153 (uint8) is greater than 127 (int8): maximum value for this type exceeded
Index ¶
- Variables
- func Convert[NumOut Number, NumIn Input](orig NumIn) (converted NumOut, err error)
- func MustConvert[NumOut Number, NumIn Input](orig NumIn) NumOut
- func RequireConvert[NumOut Number, NumIn Input](t TestingT, orig NumIn) (converted NumOut)
- func ToFloat32[T Number](i T) (float32, error)deprecated
- func ToFloat64[T Number](i T) (float64, error)deprecated
- func ToInt[T Number](i T) (int, error)deprecated
- func ToInt8[T Number](i T) (int8, error)deprecated
- func ToInt16[T Number](i T) (int16, error)deprecated
- func ToInt32[T Number](i T) (int32, error)deprecated
- func ToInt64[T Number](i T) (int64, error)deprecated
- func ToUint[T Number](i T) (uint, error)deprecated
- func ToUint8[T Number](i T) (uint8, error)deprecated
- func ToUint16[T Number](i T) (uint16, error)deprecated
- func ToUint32[T Number](i T) (uint32, error)deprecated
- func ToUint64[T Number](i T) (uint64, error)deprecated
- type Float
- type Input
- type Integer
- type Number
- type Signed
- type TestingT
- type Unsigned
Examples ¶
- Package
- Convert
- RequireConvert (Failure)
- RequireConvert (Success)
- ToFloat32
- ToFloat32 (Deprecation)
- ToFloat64
- ToFloat64 (Deprecation)
- ToInt
- ToInt (Deprecation)
- ToInt8
- ToInt8 (Deprecation)
- ToInt16
- ToInt16 (Deprecation)
- ToInt32
- ToInt32 (Deprecation)
- ToInt64
- ToInt64 (Deprecation)
- ToUint
- ToUint8
- ToUint8 (Deprecation)
- ToUint16
- ToUint16 (Deprecation)
- ToUint32
- ToUint32 (Deprecation)
- ToUint64
- ToUint64 (Deprecation)
Constants ¶
This section is empty.
Variables ¶
var ErrConversionIssue = errors.New("conversion issue")
ErrConversionIssue is a generic error for type conversion issues It is used to wrap other errors
var ErrExceedMaximumValue = errors.New("maximum value for this type exceeded")
ErrExceedMaximumValue is an error for when the value is greater than the maximum value of the desired type.
var ErrExceedMinimumValue = errors.New("minimum value for this type exceeded")
ErrExceedMinimumValue is an error for when the value is less than the minimum value of the desired type.
var ErrRangeOverflow = errors.New("range overflow")
ErrRangeOverflow is an error for when the value is outside the range of the desired type
var ErrStringConversion = errors.New("cannot convert from string")
ErrStringConversion is an error for when the conversion fails from string.
var ErrUnsupportedConversion = errors.New("unsupported type")
ErrUnsupportedConversion is an error for when the conversion is not supported from the provided type.
Functions ¶
func Convert ¶ added in v1.4.0
Convert attempts to convert any value to the desired type
- If the conversion is possible, the converted value is returned.
- If the conversion results in a value outside the range of the desired type, an ErrRangeOverflow error is wrapped in the returned error.
- If the conversion exceeds the maximum value of the desired type, an ErrExceedMaximumValue error is wrapped in the returned error.
- If the conversion exceeds the minimum value of the desired type, an ErrExceedMinimumValue error is wrapped in the returned error.
- If the conversion is not possible for the desired type, an ErrUnsupportedConversion error is wrapped in the returned error.
- If the conversion fails from string, an ErrStringConversion error is wrapped in the returned error.
- If the conversion results in an error, an ErrConversionIssue error is wrapped in the returned error.
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
b, err := safecast.Convert[int8](true)
fmt.Println(b, err)
b, err = safecast.Convert[int8]("true")
fmt.Println(b, err)
c, err := safecast.Convert[int16](17.1)
fmt.Println(c, err)
c, err = safecast.Convert[int16](int64(17))
fmt.Println(c, err)
d, err := safecast.Convert[int32]("17.1")
fmt.Println(d, err)
i, err := safecast.Convert[uint]("100_000")
fmt.Println(i, err)
i, err = safecast.Convert[uint]("0b11")
fmt.Println(i, err)
i, err = safecast.Convert[uint]("0x11")
fmt.Println(i, err)
a := int8(-1)
i, err = safecast.Convert[uint](a)
fmt.Println(i, err)
i, err = safecast.Convert[uint]("-1")
fmt.Println(i, err)
i, err = safecast.Convert[uint]("abc")
fmt.Println(i, err)
i, err = safecast.Convert[uint]("-1.1")
fmt.Println(i, err)
i, err = safecast.Convert[uint](".12345E+5")
fmt.Println(i, err)
}
Output: 1 <nil> 1 <nil> 17 <nil> 17 <nil> 17 <nil> 100000 <nil> 3 <nil> 17 <nil> 0 conversion issue: -1 (int8) is less than 0 (uint): minimum value for this type exceeded 0 conversion issue: -1 (int64) is less than 0 (uint): minimum value for this type exceeded 0 conversion issue: cannot convert from `abc` to uint (base auto-detection) 0 conversion issue: -1.1 (float64) is less than 0 (uint): minimum value for this type exceeded 12345 <nil>
func MustConvert ¶ added in v1.5.0
MustConvert calls Convert to convert the value to the desired type, and panics if the conversion fails.
func RequireConvert ¶ added in v1.7.0
RequireConvert is a test helper that calls Convert that converts the value to the desired type, and fails the test if the conversion fails.
Example (Failure) ¶
This example shows how safecast.RequireConvert reacts when the conversion fails
An error is raised via testing.T.Fatal if the conversion fails.
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
// mockTestingTExample is a mock implementation of the [safecast.TestingT] interface
// its purpose is to display the error message in the [ExampleRequireConvert_failure].
type mockTestingTExample struct {
failed bool
}
func (m *mockTestingTExample) Helper() {}
func (m *mockTestingTExample) Fatal(args ...any) {
fmt.Printf("--- FAIL:\n\t")
fmt.Println(args...)
m.failed = true
}
func (m mockTestingTExample) Failed() bool {
return m.failed
}
func main() {
t := new(mockTestingTExample) // use *testing.T, *testing.B, or *testing.F here
_ = safecast.RequireConvert[uint8](t, "foo")
// here an error is raised via [testing.T.Fatal]
}
Output: --- FAIL: conversion issue: cannot convert from `foo` to uint8 (base auto-detection)
Example (Success) ¶
This example shows how to use safecast.RequireConvert to convert a value in a test
Here t is a mock implementation of the safecast.TestingT interface you can use any type that implements this interface, such as *testing.T, *testing.B, or *testing.F
t := new(mockTestingT) out := safecast.RequireConvert[uint8](t, 42.0) fmt.Println(out, t.Failed())
Output: 42 false
func ToFloat32
deprecated
added in
v1.3.0
ToFloat32 attempts to convert any Number value to a float32. If the conversion results in a value outside the range of a float32, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[float32](i)
Example ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int8(42)
i, err := safecast.ToFloat32(a)
fmt.Println(i, err)
b := math.MaxFloat64
i, err = safecast.ToFloat32(b)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 1.7976931348623157e+308 (float64) is greater than 3.4028235e+38 (float32): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToFloat32] function.
a := int8(42)
i, err := safecast.Convert[float32](a)
fmt.Println(i, err)
b := math.MaxFloat64
_, err = safecast.Convert[float32](b)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 1.7976931348623157e+308 (float64) is greater than 3.4028235e+38 (float32): maximum value for this type exceeded
func ToFloat64
deprecated
added in
v1.3.0
ToFloat64 attempts to convert any Number value to a float64. If the conversion results in a value outside the range of a float64, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[float64](i)
Example ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int8(42)
i, err := safecast.ToFloat64(a)
fmt.Println(i, err)
b := math.MaxFloat64
i, err = safecast.ToFloat64(b)
fmt.Println(i, err)
}
Output: 42 <nil> 1.7976931348623157e+308 <nil>
Example (Deprecation) ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToFloat64] function.
a := int8(42)
i, err := safecast.Convert[float64](a)
fmt.Println(i, err)
b := math.MaxFloat64
i, err = safecast.Convert[float64](b)
fmt.Println(i, err)
}
Output: 42 <nil> 1.7976931348623157e+308 <nil>
func ToInt
deprecated
ToInt attempts to convert any Number value to an int. If the conversion results in a value outside the range of an int, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[int](i)
Example ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
a := uint64(42)
i, err := safecast.ToInt(a)
fmt.Println(i, err)
b := float32(math.MaxFloat32)
i, err = safecast.ToInt(b)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 3.4028235e+38 (float32) is greater than 9223372036854775807 (int): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToInt] function.
a := uint64(42)
i, err := safecast.Convert[int](a)
fmt.Println(i, err)
b := float32(math.MaxFloat32)
_, err = safecast.Convert[int](b)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 3.4028235e+38 (float32) is greater than 9223372036854775807 (int): maximum value for this type exceeded
func ToInt8
deprecated
ToInt8 attempts to convert any Number value to an int8. If the conversion results in a value outside the range of an int8, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[int8](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := float64(42.42)
i, err := safecast.ToInt8(a)
fmt.Println(i, err)
a = float64(200.42)
i, err = safecast.ToInt8(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 200.42 (float64) is greater than 127 (int8): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToInt8] function.
a := float64(42.42)
i, err := safecast.Convert[int8](a)
fmt.Println(i, err)
a = float64(200.42)
_, err = safecast.Convert[int8](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 200.42 (float64) is greater than 127 (int8): maximum value for this type exceeded
func ToInt16
deprecated
ToInt16 attempts to convert any Number value to an int16. If the conversion results in a value outside the range of an int16, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[int16](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int32(42)
i, err := safecast.ToInt16(a)
fmt.Println(i, err)
a = int32(40000)
i, err = safecast.ToInt16(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 40000 (int32) is greater than 32767 (int16): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToInt16] function.
a := int32(42)
i, err := safecast.Convert[int16](a)
fmt.Println(i, err)
a = int32(40000)
_, err = safecast.Convert[int16](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 40000 (int32) is greater than 32767 (int16): maximum value for this type exceeded
func ToInt32
deprecated
ToInt32 attempts to convert any Number value to an int32. If the conversion results in a value outside the range of an int32, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[int32](i)
Example ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int(42)
i, err := safecast.ToInt32(a)
fmt.Println(i, err)
b := uint32(math.MaxInt32) + 1
i, err = safecast.ToInt32(b)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 2147483648 (uint32) is greater than 2147483647 (int32): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToInt32] function.
a := int(42)
i, err := safecast.Convert[int32](a)
fmt.Println(i, err)
b := uint32(math.MaxInt32) + 1
_, err = safecast.Convert[int32](b)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 2147483648 (uint32) is greater than 2147483647 (int32): maximum value for this type exceeded
func ToInt64
deprecated
ToInt64 attempts to convert any Number value to an int64. If the conversion results in a value outside the range of an int64, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[int64](i)
Example ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
a := uint64(42)
i, err := safecast.ToInt64(a)
fmt.Println(i, err)
a = uint64(math.MaxInt64) + 1
i, err = safecast.ToInt64(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: 9223372036854775808 (uint64) is greater than 9223372036854775807 (int64): maximum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"math"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToInt64] function.
a := uint64(42)
i, err := safecast.Convert[uint64](a)
fmt.Println(i, err)
a = uint64(math.MaxInt64) + 1
_, err = safecast.Convert[int64](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: 9223372036854775808 (uint64) is greater than 9223372036854775807 (int64): maximum value for this type exceeded
func ToUint
deprecated
ToUint attempts to convert any Number value to an uint. If the conversion results in a value outside the range of an uint, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[uint](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int8(42)
i, err := safecast.ToUint(a)
fmt.Println(i, err)
a = int8(-1)
i, err = safecast.ToUint(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: -1 (int8) is less than 0 (uint): minimum value for this type exceeded
func ToUint8
deprecated
ToUint8 attempts to convert any Number value to an uint8. If the conversion results in a value outside the range of an uint8, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[uint8](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int64(42)
i, err := safecast.ToUint8(a)
fmt.Println(i, err)
a = int64(-1)
i, err = safecast.ToUint8(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: -1 (int64) is less than 0 (uint8): minimum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToUint8] function.
a := int64(42)
i, err := safecast.Convert[uint8](a)
fmt.Println(i, err)
a = int64(-1)
_, err = safecast.Convert[uint8](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: -1 (int64) is less than 0 (uint8): minimum value for this type exceeded
func ToUint16
deprecated
ToUint16 attempts to convert any Number value to an uint16. If the conversion results in a value outside the range of an uint16, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[uint16](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int64(42)
i, err := safecast.ToUint16(a)
fmt.Println(i, err)
a = int64(-1)
i, err = safecast.ToUint16(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: -1 (int64) is less than 0 (uint16): minimum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToUint16] function.
a := int64(42)
i, err := safecast.Convert[uint16](a)
fmt.Println(i, err)
a = int64(-1)
_, err = safecast.Convert[uint16](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: -1 (int64) is less than 0 (uint16): minimum value for this type exceeded
func ToUint32
deprecated
ToUint32 attempts to convert any Number value to an uint32. If the conversion results in a value outside the range of an uint32, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[uint32](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int16(42)
i, err := safecast.ToUint32(a)
fmt.Println(i, err)
a = int16(-1)
i, err = safecast.ToUint32(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: -1 (int16) is less than 0 (uint32): minimum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToUint32] function.
a := int16(42)
i, err := safecast.Convert[uint32](a)
fmt.Println(i, err)
a = int16(-1)
_, err = safecast.Convert[uint32](a)
fmt.Println(err)
}
Output:
func ToUint64
deprecated
ToUint64 attempts to convert any Number value to an uint64. If the conversion results in a value outside the range of an uint64, an ErrConversionIssue error is returned.
Deprecated: use Convert instead with Convert[uint64](i)
Example ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
a := int8(42)
i, err := safecast.ToUint64(a)
fmt.Println(i, err)
a = int8(-1)
i, err = safecast.ToUint64(a)
fmt.Println(i, err)
}
Output: 42 <nil> 0 conversion issue: -1 (int8) is less than 0 (uint64): minimum value for this type exceeded
Example (Deprecation) ¶
package main
import (
"fmt"
"github.com/ccoveille/go-safecast"
)
func main() {
// Example showing the use of the [safecast.Convert] function as a replacement for the deprecated [safecast.ToUint64] function.
a := int8(42)
i, err := safecast.Convert[uint64](a)
fmt.Println(i, err)
a = int8(-1)
_, err = safecast.Convert[uint64](a)
fmt.Println(err)
}
Output: 42 <nil> conversion issue: -1 (int8) is less than 0 (uint64): minimum value for this type exceeded
Types ¶
type Input ¶ added in v1.6.0
Input is a constraint for all types that can be used as input for Convert, and MustConvert
type Number ¶
Number is a constraint for all integers and floats TODO: consider using complex, but not sure there is a need
type Signed ¶ added in v1.1.0
Signed is a constraint for all signed integers: int, int8, int16, int32, and int64 types.
type TestingT ¶ added in v1.7.0
type TestingT interface {
Helper()
Fatal(args ...any)
}
TestingT is an interface wrapper used by RequireConvert that we need for testing purposes.
Only the methods used by RequireConvert are expected to be implemented.
*testing.T, *testing.B, or *testing.F types satisfy this interface.