
convert is a lightweight Go library for safe type conversions, preventing
truncation, overflow, or semantic loss from invalid casts. It supports
conversions between common numeric types out of the box.
It's safe to use on 32-bit and 64-bit systems.
Installation
Install via go get:
go get github.com/ctx42/convert
Example Usage
The xcast converters
// Successful cast.
ui8, err := xcast.IntToUint8(42)
fmt.Printf("xcast.IntToUint8 output: %[1]T(%[1]d) error: %v\n", ui8, err)
// Value too big for uint8.
ui8, err = xcast.IntToUint8(420)
fmt.Printf("xcast.IntToUint8 output: %[1]T(%[1]d) error: %v\n", ui8, err)
// Unsafe cast.
f32, err := xcast.IntToFloat32(xcast.Float32SafeIntMax + 1)
fmt.Printf("xcast.IntToUint8 output: %[1]T(%[1]g) error: %v\n", f32, err)
// Output:
// xcast.IntToUint8 output: uint8(42) error: <nil>
// xcast.IntToUint8 output: uint8(0) error: int value out of range for uint8
// xcast.IntToUint8 output: float32(0) error: int value out of safe range for float32
At Runtime
conv := xconv.Lookup[int, uint8]()
// Chack conv is not nil.
have, err := conv(42)
// Check conversion error.
fmt.Printf("output: %[1]T(%[1]d) error: %v", have, err)
// Output:
// output: uint8(42) error: <nil>
// By default xcast.StringToTime converter (parser) is not registered.
xconv.Register(xcast.StringToTime(time.RFC3339))
conv := xconv.Lookup[string, time.Time]()
// Chack conv is not nil.
have, err := conv("2000-01-02T03:04:05Z")
// Check conversion error.
fmt.Printf("output: %[1]s; error: %v", have.Format(time.ANSIC), err)
// Output:
// output: Sun Jan 2 03:04:05 2000; error: <nil>
Introduction
The main type used in the module is defined in the xconv package:
// Converter represents a function that attempts lossless conversion from a
// source value of type From to a target value of type To. On success, it
// returns the converted value and a nil error. On failure (e.g., truncation,
// overflow, or semantic loss), it returns the zero value of To along with a
// non-nil error describing the issue.
type Converter[From, To any] func(from From) (to To, err error)
All build in converters match the Converter.
Module is split into two packages:
xcast - converter functions like Float32ToInt8.
xconvert - registry of converters with the ability to register your own.
Built-in Converters
Package xcast provides 225 Converter functions between build-in types:
uint
uint8
uint16
uint32
uint64
int
int8
int16
int32
int64
float32
float64
byte
rune
uintqptr
All converters for the above type pairs are automatically added to xconv
package-level registry.
Some conversions are implemented only between specific type pairs:
xcast.StringToDuration
xcast.StringToString
xcast.StringToTime - time must be in time.RFC3339Nano but you can register your on formats.
Look Up Converters At Runtinme
Use xconv package to look up / register converts during runtime.
conv := xconv.Lookup[int, uint8]()
// Chack conv is not nil.
have, err := conv(42)
// Check conversion error.
fmt.Printf("output: %[1]T(%[1]d) error: %v", have, err)
// Output:
// output: uint8(42) error: <nil>
Register Custom Converters
type A struct{ val int8 }
type B struct{ val int }
// Custom converter function matching [xconv.Converter] signature.
myConv := func(from A) (to B, err error) {
return B{val: int(from.val)}, nil
}
// Register a converter function between types A and B.
old := xconv.Register(myConv)
// If there was already a converter for that source-destination type pair,
// it will be returned, nil otherwise.
_ = old
// Lookup converter registered converter.
conv := xconv.Lookup[A, B]()
// Run conversion.
have, err := conv(A{42})
fmt.Printf("output: %[1]T(%[1]d) error: %v", have, err)
// Output:
// output: xconv_test.B({42}) error: <nil>
32bit vs. 64bit Systems
In cases where its necessary module implements separate boundary checks for
32-bit dnd 64-bit systems. See files in xcast directory with
_32bit and _64bit strings in their fiolenames.