assign

A powerful Go library for type conversion and value assignment with automatic type conversion

Features

🔄 Automatic Type Conversion

Seamlessly convert between compatible types like string ↔ int, float ↔ string, and more with intelligent conversion logic.

🛡️ Type Safety

Leverage Go 1.18+ generics with type constraints for compile-time safety and better performance.

🎯 Nil Pointer Handling

Automatically initialize nil pointers when needed, eliminating common runtime panics.

🔌 Interface Support

Built-in support for TextUnmarshaler and BinaryUnmarshaler interfaces for custom types.

⚡ High Performance

Optimized fast paths for common type conversions with zero allocations for primitive types.

🔧 Extensible

Add custom type converters through extension functions for specialized conversion needs.

Quick Start

Get started with assign in minutes:

go get github.com/slipros/assign@latest
package main

import (
    "fmt"
    "reflect"
    "time"
    "github.com/slipros/assign"
)

type User struct {
    ID       int       `json:"id"`
    Name     string    `json:"name"`
    Age      int       `json:"age"`
    IsActive bool      `json:"is_active"`
    JoinedAt time.Time `json:"joined_at"`
    Scores   []int     `json:"scores"`
}

func main() {
    var user User
    v := reflect.ValueOf(&user).Elem()

    // Convert various types automatically
    if err := assign.Value(v.FieldByName("ID"), "123"); err != nil {
        panic(err)
    }
    if err := assign.Value(v.FieldByName("Name"), "John Doe"); err != nil {
        panic(err)
    }
    if err := assign.Value(v.FieldByName("Age"), "30"); err != nil {
        panic(err)
    }
    if err := assign.Value(v.FieldByName("IsActive"), "true"); err != nil {
        panic(err)
    }
    if err := assign.Value(v.FieldByName("JoinedAt"), "2023-01-15T10:30:00Z"); err != nil {
        panic(err)
    }
    if err := assign.SliceString(v.FieldByName("Scores"), []string{"85", "92", "78"}); err != nil {
        panic(err)
    }

    fmt.Printf("User: %+v\n", user)
}

API Reference

Core Functions

Value - Universal Assignment

func Value(to reflect.Value, from any, extensions ...ExtensionFunc) error

The primary entry point for type conversion and assignment. Handles nil pointer initialization, various primitive types, and interfaces with automatic type conversion.

Integer - Numeric Type Conversion

func Integer[I IntegerValue](to reflect.Value, from I) error

Converts integer values with overflow protection and range checking for all integer types.

Float - Floating Point Conversion

func Float[F FloatValue](to reflect.Value, from F) error

Handles floating-point conversions with special value support (NaN, Infinity).

String - Text Conversion

func String(to reflect.Value, from string) error

Optimized string parsing with fast paths for common type conversions.

SliceString - Array and Slice Conversion

func SliceString(to reflect.Value, from []string, options ...SliceOptionFunc) error

Convert string slices to various types with configurable separators.

Type Constraints

type SignedValue interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64
}

type UnsignedValue interface {
    ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

type IntegerValue interface {
    SignedValue | UnsignedValue
}

type FloatValue interface {
    ~float32 | ~float64
}

Examples

Basic Type Conversion

var target int
field := reflect.ValueOf(&target).Elem()

// Convert from various types
if err := assign.Value(field, "42"); err != nil {   // string to int
    panic(err)
}
if err := assign.Value(field, 3.14); err != nil {  // float to int
    panic(err)
}
if err := assign.Value(field, true); err != nil {  // bool to int (true = 1)
    panic(err)
}

Slice Operations

var intSlice []int
var joinedString string

field1 := reflect.ValueOf(&intSlice).Elem()
field2 := reflect.ValueOf(&joinedString).Elem()

// String slice to int slice
if err := assign.SliceString(field1, []string{"1", "2", "3", "4"}); err != nil {
    panic(err)
}

// String slice to joined string with custom separator
if err := assign.SliceString(field2, []string{"a", "b", "c"}, assign.WithSeparator(" | ")); err != nil {
    panic(err)
}

Time Parsing

var timestamp time.Time
field := reflect.ValueOf(×tamp).Elem()

// Supports multiple formats automatically
if err := assign.String(field, "2023-01-15T10:30:00Z"); err != nil {       // RFC3339
    panic(err)
}
if err := assign.String(field, "2023-01-15"); err != nil {                 // Date only
    panic(err)
}
if err := assign.String(field, "01/15/2023"); err != nil {                 // US format
    panic(err)
}
if err := assign.String(field, "2023-01-15 10:30:00"); err != nil {        // DateTime
    panic(err)
}

Extension Functions

import (
    "net/http"
    "reflect"
    "github.com/slipros/assign"
)

// Extension function for HTTP Cookie conversion
func cookieExtension(value any) (func(to reflect.Value) error, bool) {
    cookie, ok := value.(*http.Cookie)
    if !ok {
        return nil, false
    }

    return func(to reflect.Value) error {
        return assign.String(to, cookie.Value)
    }, true
}

// Usage
cookie := &http.Cookie{Name: "session", Value: "abc123"}
var sessionID string
field := reflect.ValueOf(&sessionID).Elem()

if err := assign.Value(field, cookie, cookieExtension); err != nil {
    panic(err)
}
// sessionID now contains "abc123"