/magic

Magic converter for different structs in Golang

Primary LanguageGoMIT LicenseMIT

magic

Tests Coverage Status Go Report Card PkgGoDev

Magic converter for different structs

By default:

  1. Map same types with same names
  2. Map slices with same types
  3. Map types to pointers and backwards (for example: int to *int)
  4. Returns error on types mismatch
  5. Returns lint of unconverted fields

By options:

  1. Custom converters for different types
  2. Custom mapping for different fields names

Examples

Simple

package main

import (
	"fmt"

	"github.com/onrik/magic/v2"
)

type User1 struct {
	ID       int
	Name     string
	Password string
	Age      int
}

type User2 struct {
	ID   int
	Name string
	Age  *int
}

func main() {
	user1 := User1{
		ID:       1,
		Name:     "John",
		Password: "111",
		Age:      21,
	}
	user2 := User2{}

	_, err := magic.Map(user1, &user2)
	fmt.Println(err)
	fmt.Printf("%+v\n", user2)
}

Custom converter

package main

import (
	"fmt"
	"reflect"

	"time"

	"github.com/onrik/magic/v2"
)

func timeToUnix(from, to reflect.Value) (bool, error) {
	t, ok := from.Interface().(time.Time)
	if !ok {
		return false, nil
	}

	_, ok = to.Interface().(int64)
	if !ok {
		return false, nil
	}

	to.SetInt(t.Unix())

	return true, nil
}

type User1 struct {
	ID       int
	Name     string
	Password string
	Age      int
	Created  time.Time
}

type User2 struct {
	ID      int
	Name    string
	Created int64
}

func main() {
	user1 := User1{
		ID:       1,
		Name:     "John",
		Password: "111",
		Age:      21,
		Created:  time.Now(),
	}
	user2 := User2{}

	_, err := magic.Map(user1, &user2, magic.WithConverters(timeToUnix))
	fmt.Println(err)
	fmt.Printf("%+v\n", user2)
}

Fields mapping

package main

import (
	"fmt"
	"time"

	"github.com/onrik/magic/v2"
)

type User1 struct {
	ID       int
	Name     string
	Password string
	Age      int
	Created  time.Time
}

type User2 struct {
	ID         int
	Name       string
	Registered time.Time
}

func main() {
	user1 := User1{
		ID:       1,
		Name:     "John",
		Password: "111",
		Age:      21,
		Created:  time.Now(),
	}
	user2 := User2{}

	_, err := magic.Map(user1, &user2, magic.WithMapping(map[string]string{
		"Created": "Registered",
	}))
	fmt.Println(err)
	fmt.Printf("%+v\n", user2)
}