Skip to main content

to

import "github.com/go-softwarelab/common/pkg/to"

Package to provides a comprehensive set of utility functions for type conversion and transformation in Go applications.

The goal of this package is to offer useful, common converters and mappers that can be easily integrated into functional programming patterns, such as being used as mapper functions with the seq package.

These utilities are designed to reduce boilerplate code and provide a consistent API for common transformation operations while maintaining type safety through generics.

Variables

ErrInvalidStringSyntax is returned when the string has invalid syntax for conversion to target type.

var ErrInvalidStringSyntax = strconv.ErrSyntax

ErrValueOutOfRange is returned when the value is out of range of the target type.

var ErrValueOutOfRange = fmt.Errorf("%w to convert", strconv.ErrRange)

Any

func Any[T any](value T) any

Any casts the value to an any type.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert a typed value to any
val := to.Any(42)
fmt.Printf("Type: %T\n", val)

// Convert a string to any
strVal := to.Any("hello")
fmt.Printf("Type: %T\n", strVal)

}

Output

Type: int
Type: string

AtLeast

func AtLeast[T types.Ordered](min T) func(value T) T

AtLeast will return a function that will clamp the value to be at least the min value. It's wrapped around NoLessThan function, to make it usable in Map functions.

See Also: NoLessThan

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Creating a function that ensures values are at least 18
ensureAdult := to.AtLeast(18)

fmt.Printf("ensureAdult(15) = %d\n", ensureAdult(15))
fmt.Printf("ensureAdult(21) = %d\n", ensureAdult(21))

}

Output

ensureAdult(15) = 18
ensureAdult(21) = 21

AtMost

func AtMost[T types.Ordered](max T) func(value T) T

AtMost will return a function that will clamp the value to be at most the max value. It's wrapped around NoMoreThan function, to make it usable in Map functions.

See Also: NoMoreThan

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Creating a function that ensures values are at most 100
ensurePercentage := to.AtMost(100)

fmt.Printf("ensurePercentage(50) = %d\n", ensurePercentage(50))
fmt.Printf("ensurePercentage(150) = %d\n", ensurePercentage(150))

}

Output

ensurePercentage(50) = 50
ensurePercentage(150) = 100

BoolFromNumber

func BoolFromNumber[V types.Number](value V) bool

BoolFromNumber will convert any number to bool 0 is false, any other number is true.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting various numeric values to bool
fmt.Println("0 ->", to.BoolFromNumber(0))
fmt.Println("1 ->", to.BoolFromNumber(1))
fmt.Println("-1 ->", to.BoolFromNumber(-1))
fmt.Println("42 ->", to.BoolFromNumber(42))
fmt.Println("0.0 ->", to.BoolFromNumber(0.0))
fmt.Println("0.1 ->", to.BoolFromNumber(0.1))

}

Output

0 -> false
1 -> true
-1 -> true
42 -> true
0.0 -> false
0.1 -> true

BoolFromString

func BoolFromString(value string) (bool, error)

BoolFromString will convert any string to bool

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting various string representations to bool
trueValue, err := to.BoolFromString("true")
fmt.Println("true ->", trueValue, err)

falseValue, err := to.BoolFromString("false")
fmt.Println("false ->", falseValue, err)

oneValue, err := to.BoolFromString("1")
fmt.Println("1 ->", oneValue, err)

zeroValue, err := to.BoolFromString("0")
fmt.Println("0 ->", zeroValue, err)

invalidValue, err := to.BoolFromString("not-a-bool")
fmt.Println("not-a-bool ->", invalidValue, err != nil)

}

Output

true -> true <nil>
false -> false <nil>
1 -> true <nil>
0 -> false <nil>
not-a-bool -> false true

CamelCase

func CamelCase(str string) string

CamelCase converts string to camel case.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert to camelCase
val := to.CamelCase("hello world")
fmt.Printf("%T(%q)\n", val, val)

val = to.CamelCase("some-kebab-case")
fmt.Printf("%T(%q)\n", val, val)

val = to.CamelCase("PascalCaseString")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("helloWorld")
string("someKebabCase")
string("pascalCaseString")

Capitalized

func Capitalized(str string) string

Capitalized converts the first character of string to upper case and the remaining to lower case.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Capitalize the first letter of each sentence
val := to.Capitalized("hello")
fmt.Printf("%T(%q)\n", val, val)

val = to.Capitalized("HELLO WORLD")
fmt.Printf("%T(%q)\n", val, val)

val = to.Capitalized("multiple. sentences. here.")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("Hello")
string("Hello world")
string("Multiple. Sentences. Here.")

Ellipsis

func Ellipsis(str string, length int) string

Ellipsis trims and truncates a string to a specified length and appends an ellipsis if truncated.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Truncate string with ellipsis
val := to.Ellipsis("This is a short string", 10)
fmt.Printf("%T(%q)\n", val, val)

val = to.Ellipsis("Short", 10)
fmt.Printf("%T(%q)\n", val, val)

val = to.Ellipsis("Little bit longer one, but with small length", 3)
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("This is...")
string("Short")
string("...")

EllipsisWith

func EllipsisWith(length int) func(str string) string

EllipsisWith returns a function that trims and truncates a string to a specified length and appends an ellipsis if truncated. It's wrapped around Ellipsis function, to make it usable in Map functions. #mapper

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Create a function that truncates strings to 10 characters
truncate := to.EllipsisWith(10)

val := truncate("This is a long string that should be truncated")
fmt.Printf("%T(%q)\n", val, val)

val = truncate("Short")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("This is...")
string("Short")

EmptyValue

func EmptyValue[T any]() T

EmptyValue returns the zero value of type.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Get zero value of int
val := to.EmptyValue[int]()
fmt.Printf("%T(%d)\n", val, val)

// Get zero value of string
strVal := to.EmptyValue[string]()
fmt.Printf("%T(%q)\n", strVal, strVal)

// Get zero value of bool
boolVal := to.EmptyValue[bool]()
fmt.Printf("%T(%v)\n", boolVal, boolVal)

}

Output

int(0)
string("")
bool(false)

Float32

func Float32[V types.SignedNumber](value V) (float32, error)

Float32 will convert any number to float

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Float32(3)
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float32(3), Error: <nil>

Float32FromString

func Float32FromString(value string) (float32, error)

Float32FromString will convert any string to float32, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Float32FromString("3.14159")
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float32(3.14159), Error: <nil>

Float32FromUnsigned

func Float32FromUnsigned[V types.Unsigned](value V) (float32, error)

Float32FromUnsigned will convert any unassigned number to float

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Float32FromUnsigned(uint(42))
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float32(42), Error: <nil>

Float64

func Float64[V types.SignedNumber](value V) (float64, error)

Float64 will convert any number to float

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Float64(3)
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float64(3), Error: <nil>

Float64FromString

func Float64FromString(value string) (float64, error)

Float64FromString will convert any string to float64, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Float64FromString("3.14159")
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float64(3.14159), Error: <nil>

Float64FromUnsigned

func Float64FromUnsigned[V types.Unsigned](value V) (float64, error)

Float64FromUnsigned will convert any unassigned number to float

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Float64FromUnsigned(uint64(42))
fmt.Printf("%T(%g), Error: %v\n", val, val, err)

}

Output

float64(42), Error: <nil>

Int

func Int[V types.SignedNumber](value V) (int, error)

Int will convert any integer to int, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int(int16(42))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int(42), Error: <nil>

Int16

func Int16[V types.SignedNumber](value V) (int16, error)

Int16 will convert any integer to int16, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int16(1000)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting out of range
valOOR, errOOR := to.Int16(40000)
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

int16(1000), Error: <nil>
int16(0), Error: true

Int16FromString

func Int16FromString(value string) (int16, error)

Int16FromString will convert any string to int16, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Int16FromString("12345")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Invalid syntax
valSyntax, errSyntax := to.Int16FromString("abc")
fmt.Printf("%T(%d), Error: %v\n", valSyntax, valSyntax, errors.Is(errSyntax, to.ErrInvalidStringSyntax))

}

Output

int16(12345), Error: <nil>
int16(0), Error: true

Int16FromUnsigned

func Int16FromUnsigned[V types.Unsigned](value V) (int16, error)

Int16FromUnsigned will convert any unsigned integer to int16, with range checks.

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int16FromUnsigned(uint(1000))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting out of range
valOOR, errOOR := to.Int16FromUnsigned(uint(40000))
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

int16(1000), Error: <nil>
int16(0), Error: true

Int32

func Int32[V types.SignedNumber](value V) (int32, error)

Int32 will convert any integer to int32, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int32(1000000)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int32(1000000), Error: <nil>

Int32FromString

func Int32FromString(value string) (int32, error)

Int32FromString will convert any string to int32, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Int32FromString("1234567")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int32(1234567), Error: <nil>

Int32FromUnsigned

func Int32FromUnsigned[V types.Unsigned](value V) (int32, error)

Int32FromUnsigned will convert any unsigned integer to int32, with range checks.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int32FromUnsigned(uint(1000000))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int32(1000000), Error: <nil>

Int64

func Int64[V types.SignedNumber](value V) (int64, error)

Int64 will convert any integer to int64, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int64(9223372036854775807)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int64(9223372036854775807), Error: <nil>

Int64FromString

func Int64FromString(value string) (int64, error)

Int64FromString will convert any string to int64, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Int64FromString("9223372036854775807")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int64(9223372036854775807), Error: <nil>

Int64FromUnsigned

func Int64FromUnsigned[V types.Unsigned](value V) (int64, error)

Int64FromUnsigned will convert any unsigned integer to int64, with range checks.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int64FromUnsigned(uint64(9223372036854775807))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int64(9223372036854775807), Error: <nil>

Int8

func Int8[V types.SignedNumber](value V) (int8, error)

Int8 will convert any integer to int8, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int8(42)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting out of range
valOOR, errOOR := to.Int8(1000)
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

int8(42), Error: <nil>
int8(0), Error: true

Int8FromString

func Int8FromString(value string) (int8, error)

Int8FromString will convert any string to int8, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.Int8FromString("100")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Out of range
valOOR, errOOR := to.Int8FromString("200")
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

int8(100), Error: <nil>
int8(0), Error: true

Int8FromUnsigned

func Int8FromUnsigned[V types.Unsigned](value V) (int8, error)

Int8FromUnsigned will convert any unsigned integer to int8, with range checks.

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.Int8FromUnsigned(uint(42))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting out of range
valOOR, errOOR := to.Int8FromUnsigned(uint(200))
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

int8(42), Error: <nil>
int8(0), Error: true

IntFromString

func IntFromString(value string) (int, error)

IntFromString will convert any string to int, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.IntFromString("12345")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Invalid syntax
valSyntax, errSyntax := to.IntFromString("abc")
fmt.Printf("%T(%d), Error: %v\n", valSyntax, valSyntax, errors.Is(errSyntax, to.ErrInvalidStringSyntax))

}

Output

int(12345), Error: <nil>
int(0), Error: true

IntFromUnsigned

func IntFromUnsigned[V types.Unsigned](value V) (int, error)

IntFromUnsigned will convert any unsigned integer to int, with range checks.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.IntFromUnsigned(uint16(42))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

int(42), Error: <nil>

KebabCase

func KebabCase(str string) string

KebabCase converts string to kebab case.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert to kebab-case
val := to.KebabCase("hello world")
fmt.Printf("%T(%q)\n", val, val)

val = to.KebabCase("camelCaseString")
fmt.Printf("%T(%q)\n", val, val)

val = to.KebabCase("PascalCaseString")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("hello-world")
string("camel-case-string")
string("pascal-case-string")

Nil

func Nil[T any]() *T

Nil returns a nil pointer of type.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Create a nil pointer of int type
val := to.Nil[int]()
fmt.Printf("%T, IsNil: %v\n", val, val == nil)

// Create a nil pointer of a struct type
type Person struct {
Name string
Age int
}
person := to.Nil[Person]()
fmt.Printf("%T, IsNil: %v\n", person, person == nil)

}

Output

*int, IsNil: true
*to_test.Person, IsNil: true

NilOfType

func NilOfType[T any](_ *T) *T

NilOfType returns a nil pointer of type.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Create a nil pointer based on existing pointer type
var existingPtr *string
nilPtr := to.NilOfType(existingPtr)
fmt.Printf("%T, IsNil: %v\n", nilPtr, nilPtr == nil)

}

Output

*string, IsNil: true

NoLessThan

func NoLessThan[T types.Ordered](value, min T) T

NoLessThan will return the value if it's not less than the min value or the min value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Already above min
val := to.NoLessThan(5, 0)
fmt.Printf("NoLessThan(5, 0) = %d\n", val)

// Below min
val = to.NoLessThan(-5, 0)
fmt.Printf("NoLessThan(-5, 0) = %d\n", val)

// Works with float values too
floatVal := to.NoLessThan(3.14, 4.0)
fmt.Printf("NoLessThan(3.14, 4.0) = %.2f\n", floatVal)

}

Output

NoLessThan(5, 0) = 5
NoLessThan(-5, 0) = 0
NoLessThan(3.14, 4.0) = 4.00

NoMoreThan

func NoMoreThan[T types.Ordered](value, max T) T

NoMoreThan will return the value if it's not more than the max value or the max value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Below max
val := to.NoMoreThan(5, 10)
fmt.Printf("NoMoreThan(5, 10) = %d\n", val)

// Above max
val = to.NoMoreThan(15, 10)
fmt.Printf("NoMoreThan(15, 10) = %d\n", val)

}

Output

NoMoreThan(5, 10) = 5
NoMoreThan(15, 10) = 10

Options

func Options[T any](opts ...func(*T)) T

Options helper function to handle options pattern.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Prepare definition of config
type Config struct {
Host string
Port int
Debug bool
}

// Define reusable option functions
withHost := func(host string) func(*Config) {
return func(c *Config) {
c.Host = host
}
}

withPort := func(port int) func(*Config) {
return func(c *Config) {
c.Port = port
}
}

withDebug := func(c *Config) {
c.Debug = true
}

// Handle opts
config := to.Options[Config](
withHost("example.com"),
withPort(443),
withDebug,
)

fmt.Printf("Host: %s\n", config.Host)
fmt.Printf("Port: %d\n", config.Port)
fmt.Printf("Debug: %v\n", config.Debug)

}

Output

Host: example.com
Port: 443
Debug: true

OptionsWithDefault

func OptionsWithDefault[T any](defaultOptions T, opts ...func(*T)) T

OptionsWithDefault helper function to handle options pattern with default value for options.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
type Config struct {
Host string
Port int
Debug bool
}

// Default configuration
defaultConfig := Config{
Host: "127.0.0.1",
Port: 3000,
Debug: false,
}

// Override some default values using OptionsWithDefault
config := to.OptionsWithDefault(defaultConfig,
func(c *Config) {
c.Port = 8080
},
func(c *Config) {
c.Debug = true
},
)

fmt.Printf("Host: %s\n", config.Host)
fmt.Printf("Port: %d\n", config.Port)
fmt.Printf("Debug: %v\n", config.Debug)

}

Output

Host: 127.0.0.1
Port: 8080
Debug: true

PascalCase

func PascalCase(str string) string

PascalCase converts string to pascal case.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert to PascalCase
val := to.PascalCase("hello world")
fmt.Printf("%T(%q)\n", val, val)

val = to.PascalCase("some-kebab-case")
fmt.Printf("%T(%q)\n", val, val)

val = to.PascalCase("snake_case_string")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("HelloWorld")
string("SomeKebabCase")
string("SnakeCaseString")

Ptr

func Ptr[T any](x T) *T

Ptr returns a pointer copy of value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Create a pointer to a value
val := to.Ptr(42)
fmt.Printf("%T(%d)\n", val, *val)

// Works with strings too
strVal := to.Ptr("hello")
fmt.Printf("%T(%q)\n", strVal, *strVal)

}

Output

*int(42)
*string("hello")

Sentences

func Sentences(str string) []string

Sentences splits string into an array of its sentences. The sentences are trimmed from leading and trailing spaces.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Splitting into sentences
text := "Hello, world! This is a test. Is this working?"
sentences := to.Sentences(text)
fmt.Printf("%#v\n", sentences)

}

Output

[]string{"Hello, world!", "This is a test.", "Is this working?"}

SliceOfAny

func SliceOfAny[T any](collection []T) []any

SliceOfAny casts the slice to a slice of any type.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert a slice of ints to a slice of any
values := []int{1, 2, 3}
anySlice := to.SliceOfAny(values)

fmt.Printf("Type: %T, Length: %d\n", anySlice, len(anySlice))
fmt.Printf("First element type: %T\n", anySlice[0])

}

Output

Type: []interface {}, Length: 3
First element type: int

SliceOfPtr

func SliceOfPtr[T any](collection []T) []*T

SliceOfPtr returns a slice of pointer copy of value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert a slice of values to a slice of pointers
values := []int{1, 2, 3}
ptrs := to.SliceOfPtr(values)

// Print first element to demonstrate it's a pointer
fmt.Printf("%T(%d)\n", ptrs[0], *ptrs[0])

// Print length to show all elements were converted
fmt.Printf("Length: %d\n", len(ptrs))

}

Output

*int(1)
Length: 3

SliceOfValue

func SliceOfValue[T any](collection []*T) []T

SliceOfValue returns a slice with the pointer values.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert a slice of pointers to a slice of values
p1, p2 := to.Ptr(10), to.Ptr(20)
ptrs := []*int{p1, p2, nil}
values := to.SliceOfValue(ptrs)

fmt.Printf("%T(%d)\n", values[0], values[0])
fmt.Printf("%T(%d)\n", values[1], values[1])
fmt.Printf("%T(%d) (zero value from nil)\n", values[2], values[2])

}

Output

int(10)
int(20)
int(0) (zero value from nil)

SnakeCase

func SnakeCase(str string) string

SnakeCase converts string to snake case.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Convert to snake_case
val := to.SnakeCase("hello world")
fmt.Printf("%T(%q)\n", val, val)

val = to.SnakeCase("camelCaseString")
fmt.Printf("%T(%q)\n", val, val)

val = to.SnakeCase("PascalCaseString")
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("hello_world")
string("camel_case_string")
string("pascal_case_string")

StringFromBool

func StringFromBool(value bool) string

StringFromBool will convert any bool to string

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Boolean to string conversion
val := to.StringFromBool(true)
fmt.Printf("%T(%q)\n", val, val)

val = to.StringFromBool(false)
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("true")
string("false")

StringFromBytes

func StringFromBytes(value []byte) string

StringFromBytes will convert any byte slice to string

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Byte slice to string conversion
val := to.StringFromBytes([]byte("hello"))
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("hello")

StringFromFloat

func StringFromFloat[V types.Float](value V) string

StringFromFloat will convert any float to string

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Float to string conversion
val := to.StringFromFloat(3.14159)
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("3.141590")

StringFromInteger

func StringFromInteger[V types.Integer](value V) string

StringFromInteger will convert any integer to string

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Integer to string conversion
val := to.StringFromInteger(42)
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("42")

StringFromRune

func StringFromRune(value rune) string

StringFromRune will convert any rune to string

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Rune to string conversion
val := to.StringFromRune('世')
fmt.Printf("%T(%q)\n", val, val)

}

Output

string("世")

UInt

func UInt[V types.Number](value V) (uint, error)

UInt will convert any integer to uint, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting positive value
val, err := to.UInt(42)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting negative value
valNeg, errNeg := to.UInt(-5)
fmt.Printf("%T(%d), Error: %v\n", valNeg, valNeg, errors.Is(errNeg, to.ErrValueOutOfRange))

}

Output

uint(42), Error: <nil>
uint(0), Error: true

UInt16

func UInt16[V types.Number](value V) (uint16, error)

UInt16 will convert any integer to uint16, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.UInt16(65000)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint16(65000), Error: <nil>

UInt16FromString

func UInt16FromString(value string) (uint16, error)

UInt16FromString will convert any string to uint16, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UInt16FromString("65000")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint16(65000), Error: <nil>

UInt32

func UInt32[V types.Number](value V) (uint32, error)

UInt32 will convert any integer to uint32, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UInt32(42)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Negative number
valNeg, errNeg := to.UInt32(-5)
fmt.Printf("%T(%d), Error: %v\n", valNeg, valNeg, errors.Is(errNeg, to.ErrValueOutOfRange))

}

Output

uint32(42), Error: <nil>
uint32(0), Error: true

UInt32FromString

func UInt32FromString(value string) (uint32, error)

UInt32FromString will convert any string to uint32, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UInt32FromString("4294967295")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint32(4294967295), Error: <nil>

UInt64

func UInt64[V types.Number](value V) (uint64, error)

UInt64 will convert any integer to uint64, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.UInt64(uint(18446744073709551000))
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint64(18446744073709551000), Error: <nil>

UInt64FromString

func UInt64FromString(value string) (uint64, error)

UInt64FromString will convert any string to uint64, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UInt64FromString("18446744073709551615")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint64(18446744073709551615), Error: <nil>

UInt8

func UInt8[V types.Number](value V) (uint8, error)

UInt8 will convert any integer to uint8, with range checks

Example
package main

import (
"errors"
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Converting within range
val, err := to.UInt8(200)
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

// Converting out of range
valOOR, errOOR := to.UInt8(300)
fmt.Printf("%T(%d), Error: %v\n", valOOR, valOOR, errors.Is(errOOR, to.ErrValueOutOfRange))

}

Output

uint8(200), Error: <nil>
uint8(0), Error: true

UInt8FromString

func UInt8FromString(value string) (uint8, error)

UInt8FromString will convert any string to uint8, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UInt8FromString("200")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint8(200), Error: <nil>

UIntFromString

func UIntFromString(value string) (uint, error)

UIntFromString will convert any string to uint, with range checks

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Valid conversion
val, err := to.UIntFromString("42")
fmt.Printf("%T(%d), Error: %v\n", val, val, err)

}

Output

uint(42), Error: <nil>

Value

func Value[T any](x *T) T

Value returns the pointer value or zero value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Get value from a pointer
ptr := to.Ptr(42)
val := to.Value(ptr)
fmt.Printf("%T(%d)\n", val, val)

// Get value from a nil pointer (returns zero value)
var nilPtr *string
strVal := to.Value(nilPtr)
fmt.Printf("%T(%q)\n", strVal, strVal)

}

Output

int(42)
string("")

ValueBetween

func ValueBetween[T types.Ordered](value, min, max T) T

ValueBetween will clamp the value between the min and max values. In other words it ensures that result is min <= value <= max. For value that is less than min, it will return min. For value that is greater than max, it will return max.

See Also: ValueBetweenThe to use it in Map functions.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Within range
val := to.ValueBetween(5, 0, 10)
fmt.Printf("ValueBetween(5, 0, 10) = %d\n", val)

// Lower than min
val = to.ValueBetween(-5, 0, 10)
fmt.Printf("ValueBetween(-5, 0, 10) = %d\n", val)

// Higher than max
val = to.ValueBetween(15, 0, 10)
fmt.Printf("ValueBetween(15, 0, 10) = %d\n", val)

}

Output

ValueBetween(5, 0, 10) = 5
ValueBetween(-5, 0, 10) = 0
ValueBetween(15, 0, 10) = 10

ValueBetweenThe

func ValueBetweenThe[T types.Ordered](min, max T) func(value T) T

ValueBetweenThe returns a function that clamps the value between the min and max values. In other words it ensures that result is min <= value <= max. For value that is less than min, it will return min. For value that is greater than max, it will return max. It's wrapped around ValueBetween function, to make it usable in Map functions.

See Also: ValueBetween

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Creating a percentage validator (0-100)
validatePercentage := to.ValueBetweenThe(0, 100)

fmt.Printf("validatePercentage(-20) = %d\n", validatePercentage(-20))
fmt.Printf("validatePercentage(50) = %d\n", validatePercentage(50))
fmt.Printf("validatePercentage(150) = %d\n", validatePercentage(150))

}

Output

validatePercentage(-20) = 0
validatePercentage(50) = 50
validatePercentage(150) = 100

ValueOr

func ValueOr[T any](x *T, fallback T) T

ValueOr returns the pointer value or the fallback value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Get value from a pointer
ptr := to.Ptr(42)
val := to.ValueOr(ptr, 0)
fmt.Printf("%T(%d)\n", val, val)

// Get fallback value from a nil pointer
var nilPtr *string
strVal := to.ValueOr(nilPtr, "fallback")
fmt.Printf("%T(%q)\n", strVal, strVal)

}

Output

int(42)
string("fallback")

Words

func Words(str string) []string

Words splits string into an array of its words.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Splitting into words
camelCase := to.Words("camelCaseString")
fmt.Printf("%#v\n", camelCase)

pascalCase := to.Words("PascalCaseString")
fmt.Printf("%#v\n", pascalCase)

withNumbers := to.Words("Int8Value")
fmt.Printf("%#v\n", withNumbers)

withSpaces := to.Words(" hello world ")
fmt.Printf("%#v\n", withSpaces)

}

Output

[]string{"camel", "Case", "String"}
[]string{"Pascal", "Case", "String"}
[]string{"Int", "8", "Value"}
[]string{"hello", "world"}

ZeroValue

func ZeroValue[T any]() T

ZeroValue returns the zero value of type. alias: EmptyValue

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Get zero value of int
val := to.ZeroValue[int]()
fmt.Printf("%T(%d)\n", val, val)

// Get zero value of string
strVal := to.ZeroValue[string]()
fmt.Printf("%T(%q)\n", strVal, strVal)

}

Output

int(0)
string("")

type IfElseCondition

IfElseCondition is a struct that provides a fluent API for conditional value mapping.

type IfElseCondition[T any] struct {
// contains filtered or unexported fields
}

If

func If[T any](condition bool, resultProvider func() T) *IfElseCondition[T]

If creates a new IfElseCondition with the given condition and result provider.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using If with function providers
result := to.If(true, func() string {
return "condition is true"
}).Else(func() string {
return "condition is false"
})
fmt.Println(result)

result = to.If(false, func() string {
return "condition is true"
}).Else(func() string {
return "condition is false"
})
fmt.Println(result)

}

Output

condition is true
condition is false

IfThen

func IfThen[T any](condition bool, resultWhenTrue T) *IfElseCondition[T]

IfThen creates a new IfElseCondition with the given condition and result.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using IfThen with direct values
result := to.IfThen(true, "condition is true").ElseThen("condition is false")
fmt.Println(result)

result = to.IfThen(false, "condition is true").ElseThen("condition is false")
fmt.Println(result)

}

Output

condition is true
condition is false

*IfElseCondition[T].Else

func (c *IfElseCondition[T]) Else(resultProvider func() T) T

Else accepts the default result provider and returns the result of the condition evaluation.

*IfElseCondition[T].ElseIf

func (c *IfElseCondition[T]) ElseIf(condition bool, resultProvider func() T) *IfElseCondition[T]

ElseIf adds an else if condition.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using ElseIf for multiple conditions
age := 25
result := to.If(age < 18, func() string {
return "minor"
}).ElseIf(age < 65, func() string {
return "adult"
}).Else(func() string {
return "senior"
})
fmt.Println(result)

// Testing with different age
age = 70
result = to.If(age < 18, func() string {
return "minor"
}).ElseIf(age < 65, func() string {
return "adult"
}).Else(func() string {
return "senior"
})
fmt.Println(result)

}

Output

adult
senior

*IfElseCondition[T].ElseIfThen

func (c *IfElseCondition[T]) ElseIfThen(condition bool, resultWhenTrue T) *IfElseCondition[T]

ElseIfThen adds an else if condition with a result.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using ElseIfThen for multiple conditions with direct values
score := 85
grade := to.IfThen(score >= 90, "A").
ElseIfThen(score >= 80, "B").
ElseIfThen(score >= 70, "C").
ElseIfThen(score >= 60, "D").
ElseThen("F")
fmt.Println(grade)

}

Output

B

*IfElseCondition[T].ElseThen

func (c *IfElseCondition[T]) ElseThen(resultWhenFalse T) T

ElseThen accepts the default result and returns the result of the condition evaluation.

type SwitchCase

SwitchCase provides a fluent API for conditional (switch-like) value mapping. Represents case predicates.

type SwitchCase[V comparable, R any] interface {
// Case adds a case that compares equality to case value.
Case(value V) SwitchThen[V, R]
// When adds a case predicate function.
When(func(V) bool) SwitchThen[V, R]
// Default adds a default value.
Default(R) R
}
Example (7hen)
package main

import (
"fmt"
"strings"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using Switch with When for custom predicates
text := "HELLO"

result := to.Switch[string, string](text).
When(func(s string) bool { return s == "" }).
ThenValue("Empty string").
When(func(s string) bool { return len(s) < 5 }).
ThenValue("Short string").
When(func(s string) bool { return strings.ToUpper(s) == s }).
ThenValue("All uppercase").
Default("Normal string")

fmt.Println(result)

}

Output

All uppercase

Switch

func Switch[V comparable, R any](value V) SwitchCase[V, R]

Switch creates a new SwitchCase for the given value.

Example
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using Switch with Case for equality comparisons
dayNum := 3
dayName := to.Switch[int, string](dayNum).
Case(1).ThenValue("Monday").
Case(2).ThenValue("Tuesday").
Case(3).ThenValue("Wednesday").
Case(4).ThenValue("Thursday").
Case(5).ThenValue("Friday").
Case(6).ThenValue("Saturday").
Case(7).ThenValue("Sunday").
Default("Invalid day")

fmt.Println(dayName)

}

Output

Wednesday

type SwitchThen

SwitchThen provides a fluent API for conditional (switch-like) value mapping. Represents case results.

type SwitchThen[V comparable, R any] interface {
// Then adds a result provider function for given case.
Then(func(V) R) SwitchCase[V, R]
// ThenValue adds a result value for given case.
ThenValue(R) SwitchCase[V, R]
}
Example (4hen)
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using Switch with Then for computed results
number := 15

result := to.Switch[int, string](number).
Case(0).Then(func(int) string { return "Zero" }).
When(func(n int) bool { return n%3 == 0 && n%5 == 0 }).Then(func(n int) string {
return fmt.Sprintf("FizzBuzz: %d", n)
}).
Default("Number")

fmt.Println(result)

}

Output

FizzBuzz: 15
Example (4hen Value)
package main

import (
"fmt"

"github.com/go-softwarelab/common/pkg/to"
)

func main() {
// Using Switch with Then for computed results
number := 15

result := to.Switch[int, string](number).
Case(0).ThenValue("Zero").
When(func(n int) bool { return n%3 == 0 }).ThenValue("Fizz").
When(func(n int) bool { return n%5 == 0 }).ThenValue("Buzz").
Default("Number")

fmt.Println(result)

}

Output

Fizz