Convert Figma logo to code with AI

jinzhu logocopier

Copier for golang, copy value from struct to struct and more

5,435
480
5,435
67

Top Related Projects

37,918

A Commander for modern Go CLI interactions

1,730

A Go library for implementing command-line interfaces.

3,493

CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

4,795

✨ #PTerm is a modern Go module to easily beautify console output. Featuring charts, progressbars, tables, trees, text input, select menus and much more 🚀 It's completely configurable and 100% cross-platform compatible.

Quick Overview

Copier is a Go library designed for efficient copying of values between different types. It provides a simple and flexible way to copy data from one struct to another, even when the structures have different field names or types. This library is particularly useful for mapping data between models, DTOs, and other data structures in Go applications.

Pros

  • Supports copying between different types with minimal configuration
  • Handles nested structures and slices efficiently
  • Provides options for customizing the copying process
  • Lightweight and easy to integrate into existing projects

Cons

  • May not handle all complex scenarios without additional configuration
  • Limited support for copying unexported fields
  • Documentation could be more comprehensive
  • Might introduce unexpected behavior if not used carefully

Code Examples

  1. Basic copying between structs:
type User struct {
    Name string
    Age  int
}

type UserDTO struct {
    FullName string
    Age      int
}

user := User{Name: "John Doe", Age: 30}
var userDTO UserDTO

copier.Copy(&userDTO, &user)
fmt.Printf("%+v\n", userDTO) // Output: {FullName:John Doe Age:30}
  1. Copying with field name mapping:
type Source struct {
    Field1 string
    Field2 int
}

type Destination struct {
    CustomField1 string
    CustomField2 int
}

source := Source{Field1: "Hello", Field2: 42}
var dest Destination

copier.CopyWithOption(&dest, &source, copier.Option{
    FieldMapping: map[string]string{
        "Field1": "CustomField1",
        "Field2": "CustomField2",
    },
})
fmt.Printf("%+v\n", dest) // Output: {CustomField1:Hello CustomField2:42}
  1. Copying slices:
type Item struct {
    Name  string
    Value int
}

source := []Item{{Name: "Item1", Value: 10}, {Name: "Item2", Value: 20}}
var dest []Item

copier.Copy(&dest, &source)
fmt.Printf("%+v\n", dest) // Output: [{Name:Item1 Value:10} {Name:Item2 Value:20}]

Getting Started

To use Copier in your Go project, follow these steps:

  1. Install the library:

    go get github.com/jinzhu/copier
    
  2. Import the library in your Go file:

    import "github.com/jinzhu/copier"
    
  3. Use the Copy or CopyWithOption function to copy data between structs:

    var dest DestType
    copier.Copy(&dest, &source)
    

That's it! You can now start using Copier to efficiently copy data between different types in your Go application.

Competitor Comparisons

37,918

A Commander for modern Go CLI interactions

Pros of Cobra

  • Robust CLI application framework with built-in command structure and flags
  • Extensive documentation and large community support
  • Generates boilerplate code and man pages automatically

Cons of Cobra

  • Steeper learning curve for simple CLI tools
  • More complex setup process compared to lightweight alternatives
  • Potentially overkill for small projects or single-command applications

Code Comparison

Cobra:

var rootCmd = &cobra.Command{
  Use:   "app",
  Short: "A brief description of your application",
  Run: func(cmd *cobra.Command, args []string) {
    // Your code here
  },
}

Copier:

type Config struct {
  Name string
}

err := copier.Copy(&dst, &src)
if err != nil {
  // Handle error
}

Summary

Cobra is a powerful CLI framework for Go, offering robust features and extensive documentation. It excels in creating complex, multi-command applications but may be overwhelming for simpler projects. Copier, on the other hand, is a lightweight library focused on copying struct and field values, making it more suitable for specific data manipulation tasks rather than full CLI application development.

1,730

A Go library for implementing command-line interfaces.

Pros of cli

  • More comprehensive CLI framework with built-in features like command parsing and help generation
  • Better suited for complex command-line applications with multiple subcommands
  • Actively maintained with regular updates and contributions

Cons of cli

  • Steeper learning curve due to more complex API and features
  • May be overkill for simple CLI tools or scripts
  • Requires more boilerplate code to set up basic functionality

Code Comparison

cli:

c := cli.NewCLI("app", "1.0.0")
c.Args = os.Args[1:]
c.Commands = map[string]cli.CommandFactory{
    "foo": fooCommandFactory,
}

copier:

copier.Copy(&dest, &src)

Summary

cli is a robust framework for building complex command-line applications in Go, offering features like command parsing and help generation. It's well-maintained but may have a steeper learning curve.

copier, on the other hand, is a simpler library focused on copying struct and field values. It's more lightweight and easier to use for basic object copying tasks but lacks CLI-specific features.

Choose cli for full-fledged CLI applications and copier for straightforward struct copying operations.

3,493

CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

Pros of Kingpin

  • Focused on command-line flag parsing and application structure
  • Provides a more intuitive and expressive API for defining CLI commands and flags
  • Offers built-in help generation and version flag support

Cons of Kingpin

  • Limited to CLI application development, unlike Copier's broader file templating capabilities
  • May have a steeper learning curve for simple flag parsing tasks
  • Less flexibility for general-purpose file manipulation and generation

Code Comparison

Kingpin:

var (
  verbose = kingpin.Flag("verbose", "Verbose mode.").Short('v').Bool()
  name    = kingpin.Arg("name", "Name of user.").Required().String()
)

func main() {
  kingpin.Parse()
  fmt.Printf("%v, %s\n", *verbose, *name)
}

Copier:

from copier import copy

copy(
    "template",
    "destination",
    data={"name": "John Doe", "age": 30},
    exclude=["*.pyc", "__pycache__"],
)

Summary

Kingpin is a Go library specifically designed for building command-line applications with a focus on flag parsing and application structure. It offers a more intuitive API for defining CLI commands and flags, along with built-in help generation. However, it's limited to CLI development and may have a steeper learning curve for simple tasks.

Copier, on the other hand, is a Python library for file templating and project scaffolding. It provides more flexibility for general-purpose file manipulation and generation but lacks the specific CLI-focused features of Kingpin.

4,795

✨ #PTerm is a modern Go module to easily beautify console output. Featuring charts, progressbars, tables, trees, text input, select menus and much more 🚀 It's completely configurable and 100% cross-platform compatible.

Pros of pterm

  • Focused on terminal output styling and formatting
  • Extensive set of pre-built components for terminal UI
  • Active development with frequent updates

Cons of pterm

  • Limited to terminal output, not a general-purpose file manipulation tool
  • Steeper learning curve for complex terminal UI components
  • Larger dependency footprint

Code Comparison

pterm example:

pterm.DefaultHeader.WithFullWidth().Println("Hello, World!")
pterm.Info.Println("This is a simple example")
pterm.Println("Goodbye!")

copier example:

err := copier.Copy(&dest, src)
if err != nil {
    log.Fatal(err)
}

Key Differences

pterm is a Go library for creating rich terminal output with various styling options and UI components. It's ideal for building interactive CLI applications with visually appealing interfaces.

copier, on the other hand, is a Go library for deep copying structs and slices. It's useful for data manipulation and object cloning tasks, particularly when working with complex data structures.

While both are Go libraries, they serve entirely different purposes. pterm enhances terminal output, while copier focuses on data copying and manipulation. The choice between them depends on whether you need to create rich terminal UIs or perform deep copying of data structures in your Go projects.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Copier

I am a copier, I copy everything from one to another

test status

Key Features

  • Field-to-field and method-to-field copying based on matching names
  • Support for copying data:
    • From slice to slice
    • From struct to slice
    • From map to map
  • Field manipulation through tags:
    • Enforce field copying with copier:"must"
    • Override fields even when IgnoreEmpty is set with copier:"override"
    • Exclude fields from being copied with copier:"-"

Getting Started

Installation

To start using Copier, install Go and run go get:

go get -u github.com/jinzhu/copier

Basic

Import Copier into your application to access its copying capabilities

import "github.com/jinzhu/copier"

Basic Copying

type User struct {
	Name string
	Role string
	Age  int32
}

func (user *User) DoubleAge() int32 {
	return 2 * user.Age
}

type Employee struct {
	Name      string
	Age       int32
	DoubleAge int32
	SuperRole string
}

func (employee *Employee) Role(role string) {
	employee.SuperRole = "Super " + role
}

func main() {
	user := User{Name: "Jinzhu", Age: 18, Role: "Admin"}
	employee := Employee{}

	copier.Copy(&employee, &user)
	fmt.Printf("%#v\n", employee)
	// Output: Employee{Name:"Jinzhu", Age:18, DoubleAge:36, SuperRole:"Super Admin"}
}

Tag Usage Examples

copier:"-" - Ignoring Fields

Fields tagged with copier:"-" are explicitly ignored by Copier during the copying process.

type Source struct {
    Name   string
    Secret string // We do not want this to be copied.
}

type Target struct {
    Name   string
    Secret string `copier:"-"`
}

func main() {
    source := Source{Name: "John", Secret: "so_secret"}
    target := Target{}

    copier.Copy(&target, &source)
    fmt.Printf("Name: %s, Secret: '%s'\n", target.Name, target.Secret)
    // Output: Name: John, Secret: ''
}

copier:"must" - Enforcing Field Copy

The copier:"must" tag forces a field to be copied, resulting in a panic or an error if the field cannot be copied.

type MandatorySource struct {
	Identification int
}

type MandatoryTarget struct {
	ID int `copier:"must"` // This field must be copied, or it will panic/error.
}

func main() {
	source := MandatorySource{}
	target := MandatoryTarget{ID: 10}

	// This will result in a panic or an error since ID is a must field but is empty in source.
	if err := copier.Copy(&target, &source); err != nil {
		log.Fatal(err)
	}
}

copier:"must,nopanic" - Enforcing Field Copy Without Panic

Similar to copier:"must", but Copier returns an error instead of panicking if the field is not copied.

type SafeSource struct {
	ID string
}

type SafeTarget struct {
	Code string `copier:"must,nopanic"` // Enforce copying without panic.
}

func main() {
	source := SafeSource{}
	target := SafeTarget{Code: "200"}

	if err := copier.Copy(&target, &source); err != nil {
		log.Fatalln("Error:", err)
	}
	// This will not panic, but will return an error due to missing mandatory field.
}

copier:"override" - Overriding Fields with IgnoreEmpty

Fields tagged with copier:"override" are copied even if IgnoreEmpty is set to true in Copier options and works for nil values.

type SourceWithNil struct {
    Details *string
}

type TargetOverride struct {
    Details *string `copier:"override"` // Even if source is nil, copy it.
}

func main() {
    details := "Important details"
    source := SourceWithNil{Details: nil}
    target := TargetOverride{Details: &details}

    copier.CopyWithOption(&target, &source, copier.Option{IgnoreEmpty: true})
    if target.Details == nil {
        fmt.Println("Details field was overridden to nil.")
    }
}

Specifying Custom Field Names

Use field tags to specify a custom field name when the source and destination field names do not match.

type SourceEmployee struct {
    Identifier int64
}

type TargetWorker struct {
    ID int64 `copier:"Identifier"` // Map Identifier from SourceEmployee to ID in TargetWorker
}

func main() {
    source := SourceEmployee{Identifier: 1001}
    target := TargetWorker{}

    copier.Copy(&target, &source)
    fmt.Printf("Worker ID: %d\n", target.ID)
    // Output: Worker ID: 1001
}

Other examples

Copy from Method to Field with Same Name

Illustrates copying from a method to a field and vice versa.

// Assuming User and Employee structs defined earlier with method and field respectively.

func main() {
    user := User{Name: "Jinzhu", Age: 18}
    employee := Employee{}

    copier.Copy(&employee, &user)
    fmt.Printf("DoubleAge: %d\n", employee.DoubleAge)
    // Output: DoubleAge: 36, demonstrating method to field copying.
}

Copy Struct to Slice

func main() {
    user := User{Name: "Jinzhu", Age: 18, Role: "Admin"}
    var employees []Employee

    copier.Copy(&employees, &user)
    fmt.Printf("%#v\n", employees)
    // Output: []Employee{{Name: "Jinzhu", Age: 18, DoubleAge: 36, SuperRole: "Super Admin"}}
}

Copy Slice to Slice

func main() {
    users := []User{{Name: "Jinzhu", Age: 18, Role: "Admin"}, {Name: "jinzhu 2", Age: 30, Role: "Dev"}}
    var employees []Employee

    copier.Copy(&employees, &users)
    fmt.Printf("%#v\n", employees)
    // Output: []Employee{{Name: "Jinzhu", Age: 18, DoubleAge: 36, SuperRole: "Super Admin"}, {Name: "jinzhu 2", Age: 30, DoubleAge: 60, SuperRole: "Super Dev"}}
}

Copy Map to Map

func main() {
    map1 := map[int]int{3: 6, 4: 8}
    map2 := map[int32]int8{}

    copier.Copy(&map2, map1)
    fmt.Printf("%#v\n", map2)
    // Output: map[int32]int8{3:6, 4:8}
}

Complex Data Copying: Nested Structures with Slices

This example demonstrates how Copier can be used to copy data involving complex, nested structures, including slices of structs, to showcase its ability to handle intricate data copying scenarios.

package main

import (
	"fmt"
	"github.com/jinzhu/copier"
)

type Address struct {
	City    string
	Country string
}

type Contact struct {
	Email  string
	Phones []string
}

type Employee struct {
	Name      string
	Age       int32
	Addresses []Address
	Contact   *Contact
}

type Manager struct {
	Name            string `copier:"must"`
	Age             int32  `copier:"must,nopanic"`
	ManagedCities   []string
	Contact         *Contact `copier:"override"`
	SecondaryEmails []string
}

func main() {
	employee := Employee{
		Name: "John Doe",
		Age:  30,
		Addresses: []Address{
			{City: "New York", Country: "USA"},
			{City: "San Francisco", Country: "USA"},
		},
		Contact: nil,
	}

	manager := Manager{
		ManagedCities: []string{"Los Angeles", "Boston"},
		Contact: &Contact{
			Email:  "john.doe@example.com",
			Phones: []string{"123-456-7890", "098-765-4321"},
		}, // since override is set this should be overridden with nil
		SecondaryEmails: []string{"secondary@example.com"},
	}

	copier.CopyWithOption(&manager, &employee, copier.Option{IgnoreEmpty: true, DeepCopy: true})

	fmt.Printf("Manager: %#v\n", manager)
	// Output: Manager struct showcasing copied fields from Employee,
	// including overridden and deeply copied nested slices.
}

Available tags

TagDescription
copier:"-"Explicitly ignores the field during copying.
copier:"must"Forces the field to be copied; Copier will panic or return an error if the field is not copied.
copier:"nopanic"Copier will return an error instead of panicking.
copier:"override"Forces the field to be copied even if IgnoreEmpty is set. Useful for overriding existing values with empty ones
FieldNameSpecifies a custom field name for copying when field names do not match between structs.

Contributing

You can help to make the project better, check out http://gorm.io/contribute.html for things you can do.

Author

jinzhu

License

Released under the MIT License.