Categorygithub.com/scottish-ep/structcopier
repositorypackage
0.4.7
Repository: https://github.com/scottish-ep/structcopier.git
Documentation: pkg.go.dev

# README

structcopier

Build Status

This package is copy from deepcopier of Ulule team. Due to deepcopier hasn't updated for a long time, I created this repo to fix some bugs and extend some new features. structcopier is meant to make copying of structs to/from others structs a bit easier.

Installation

go get -u github.com/scottish-ep/structcopier

Usage

// Deep copy instance1 into instance2
Copy(instance1).To(instance2)

// Deep copy instance1 into instance2 and passes the following context (which
// is basically a map[string]interface{}) as first argument
// to methods of instance2 that defined the struct tag "context".
Copy(instance1).WithContext(map[string]interface{}{"foo": "bar"}).To(instance2)

// Deep copy instance2 into instance1
Copy(instance1).From(instance2)

// Deep copy instance2 into instance1 and filter some fields
Copy(instance1).Filter(filters).To(instance2)

// Deep copy instance2 into instance1 and passes the following context (which
// is basically a map[string]interface{}) as first argument
// to methods of instance1 that defined the struct tag "context".
Copy(instance1).WithContext(map[string]interface{}{"foo": "bar"}).From(instance2)

Available options for structcopier struct tag:

OptionDescription
fieldField or method name in source instance
contextTakes a map[string]interface{} as first argument (for methods)
forceSet the value of a sql.Null* field (instead of copying the struct)
filterIgnore some fields when copy

Options example:

type Source struct {
    Name                         string
    SkipMe                       string
    SQLNullStringToSQLNullString sql.NullString
    SQLNullStringToString        sql.NullString

}

func (Source) MethodThatTakesContext(c map[string]interface{}) string {
    return "whatever"
}

type Destination struct {
    FieldWithAnotherNameInSource      string         `structcopier:"field:Name"`
    SkipMe                            string         `structcopier:"skip"`
    MethodThatTakesContext            string         `structcopier:"context"`
    SQLNullStringToSQLNullString      sql.NullString
    SQLNullStringToString             string         `structcopier:"force"`
}

Example:

package main

import (
    "fmt"

    "github.com/scottish-ep/structcopier"
)

// Model
type User struct {
    // Basic string field
    Name  string
    // structcopier supports https://golang.org/pkg/database/sql/driver/#Valuer
    Email sql.NullString
}

func (u *User) MethodThatTakesContext(ctx map[string]interface{}) string {
    // do whatever you want
    return "hello from this method"
}

// Resource
type UserResource struct {
    DisplayName            string `structcopier:"field:Name"`
    SkipMe                 string `structcopier:"skip"`
    MethodThatTakesContext string `structcopier:"context"`
    Email                  string `structcopier:"force"`

}

func main() {
    user := &User{
        Name: "gilles",
        Email: sql.NullString{
            Valid: true,
            String: "[email protected]",
        },
    }

    resource := &UserResource{}
    // copy all fields from user to resource based on struct tag
    structcopier.Copy(user).To(resource)

    // ignore name when copy from user to resource
    filters := map[string]interface{}{
        "fields" : []string{"Name"},
    }
    structcopier.Copy(user).Filter(filters).To(resource)

    // skip
    fmt.Println(resource.DisplayName)
    fmt.Println(resource.Email)
}