Skip to content

✨ Generics based Go library for casting one type to another in simple way.

License

Notifications You must be signed in to change notification settings

the-go-tool/cast

Repository files navigation

GoDoc GitHub go.mod Go version Coverage Go Report Card codebeat badge example workflow

✨ Cast

Generics based GoLang library to allow type to type casting. No extra dependencies.

🚧 The module under construction! 🚧

📦 Install

go get -u github.com/the-go-tool/cast

🚀 Usage

As long as the module uses generics Go 1.18 or above must be installed. Learn more about generics if you haven't.

Key feature that we have only several methods with type inference to make casts. Let's look at the example:

str := "42"
i := cast.To[int](str)
// Result: i is int(42) now

It's possible to use any of primitive types like all types of int, uint, bool, string and their derivatives also. Another example with custom type based on primitive value:

package main

import (
    "fmt"
    "github.com/the-go-tool/cast"
)

type Custom string

func main() {
    custom := cast.To[Custom](256)
    fmt.Println(custom) // string "256"
}

#️⃣ Error Handling

We learned about most common function cast.To. But what if our program can't cast one type to other by some reason? For example, we're trying to cast string "non-int" to int. In this case we'll get int(0) and won't know about error via cast.To.

Another one used function is cast.WithError which returns casted value and error if it happens:

i, err := cast.WithError[int]("non-int")
fmt.Println(i) // int(0) so it's default value for int
fmt.Println(err) // "strconv.ParseInt: parsing "non-int": invalid syntax"

Also we can check casting possibility like so:

if cast.Possible[int]("non-int") {
    fmt.Println("casting possible")
} else {
    fmt.Println("mission impossible") // will print
}

And very rare case when we need to panic in case of impossible casting:

i := cast.MustTo[int]("non-int") // panics

#️⃣ Casting Extension

This module has flexible API. So, you can register your own type for casting:

type Custom int

func init() {
    MustRegister(func(in Custom) (out int, err error) {
		return int(in), nil
	})
}

Now we can use Custom -> int casting like so:

func main() {
    fmt.Println(cast.To[int](Custom(5))) // int 5
}

It's going to be tedious to write casting function for each types. But this module provides casting proxies. Look:

MustRegisterProxy[Custom, string, int]() // Input, Output, Proxy
fmt.Println(cast.To[string](Custom(5))) // string 5

Because we already registered Custom -> int and we have default int -> string casters just register chain Custom -> int -> string.

🔄 Built-in Casters

Related Cross Casting (RelatedXCast)

Casting between related types but different sizes.

To[int](int32(5)) //> int(5)
To[uint8](uint16(500)) //> uint8(244), so 500-256=244
To[float32](float64(6.9)) //> float32(6.9)
To[byte](uint(5)) //> uint8(5), so byte is alias for uint8
To[rune](int(50)) //> int32(50), so rune is alias for int32
Type X X from/to X
ints
uints
floats
complexes

Number Cross Casting (NumberXCast)

Casting between number types (with possible different sizes).

To[int](56.6) //> int(56), only integer part
To[float32](56) //> float32(56)
To[uint8](int8(-40)) //> uint8(216), so 256-40=216
To[uint64](int8(-1)) //> uint64(MAX_VALUE)
To[float32](complex(5, -1)) //> float32(5)
Type N1 Type N2 N1 from/to N2
ints uints
ints floats
ints complexes
uints floats
uints complexes
floats complexes

String Cross Casting (StringXCast)

Casting between string and anything basic type. Usually, it's close to strconv standard behavior except boolean.

Casting from string to boolean extended and accepts any of 1, +, t, true, y, yes as true and any of 0, -, f, false, n, no as false. It's space trimmed and case insensitive. Any other string values will produce an error.

To[bool]("y") //> true
To[bool]("  1 ") //> true
To[bool](" n  ") //> false
To[bool](" dsa ") //> false, and error for WithError
To[string](true) //> "true"
To[string](complex(-1, -2)) //> "(-1-2i)"
To[int]("-5") //> int(-5)
To[int]("+5") //> int(5)
To[int]("5.6") //> int(0), and error for WithError
To[float32]("5.6") //> float32(5.6)
Type S Type A S from/to A
string ints
string uints
string floats
string complexes
string bool

Boolean to Number Types Casting (BoolNumCast)

Casting between boolean and number types. true alway will be 1 if cast to number or 1+0i for complexes. Number will true if value isn't equal 0. For complexes only real part is matter.

To[int](true) //> int(1)
To[int](false) //> int(0)
To[bool](int(0)) //> false
To[bool](int(-1)) //> true
To[bool](uint(1)) //> true
To[bool](complex(0, 5)) //> false, so only real part matter
To[bool](complex(5, 0)) //> true
Type B Cast N B from/to N
bool ints
bool uints
bool floats
bool complexes

🔗 Similar Projects

Please, star this repository if you find it helpful ⭐
Also, make an issue if you found a bug or would like for some improvements.

If this module doesn't fit here is links to similar projects: