copier

repository·master·Indexed 27 days ago

https://github.com/jinzhu/copier

A Go library for copying data between different types, including structs, slices, and maps, based on matching field names or custom tags. It provides functionality for basic copying via copier.Copy and advanced configuration through copier.CopyWithOption, supporting deep copies, ignoring empty values, and custom type converters. Field behavior can be controlled using struct tags for ignoring, forcing, or mapping fields.

Tokens
2.2K
Snippets
7
Records
14
Agent score
88%

What's inside copier

  1. Enforce field copying without panicking

    master

    To ensure a field is copied but avoid application panics if it fails, use the copier:"must,nopanic" tag. In this mode, copier.Copy will return an error if the mandatory field is not found in the source.

    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)
    	}
    }
  2. Map source fields to different target names

    master

    If the source and destination field names do not match, use the tag copier:"SourceFieldName" on the target struct field to define the mapping.

    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)
    }
  3. Override fields when using `IgnoreEmpty`

    master

    When using copier.CopyWithOption with copier.Option{IgnoreEmpty: true}, fields with the copier:"override" tag will be copied even if the source value is empty or nil. This allows you to explicitly set a target field to a nil or zero value.

    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})
    }
  4. Perform basic copying with `copier.Copy`

    master

    Use copier.Copy(destination, source) to copy data from one object to another. Copier supports field-to-field and method-to-field copying based on matching names. It also supports copying between slices, structs, and maps.

    import "github.com/jinzhu/copier"
    
    type User struct {
    	Name string
    	Role string
    	Age  int32
    }
    
    type Employee struct {
    	Name      string
    	Age       int32
    	SuperRole string
    }
    
    func main() {
    	user := User{Name: "Jinzhu", Age: 18, Role: "Admin"}
    	employee := Employee{}
    
    	copier.Copy(&employee, &user)
    }
  5. Configure field copying using struct tags

    master

    You can control how fields are handled during the copying process by using the copier struct tag. Supported tags include:

    • copier:"-": Explicitly ignores the field.
    • copier:"must": Forces the field to be copied; results in a panic or error if the field is missing in the source.
    • copier:"nopanic": Used with must to return an error instead of panicking.
    • copier:"override": Forces the field to be copied even if IgnoreEmpty is set in the options (useful for overriding values with nil/empty values).
    • copier:"FieldName": Maps a source field with a different name to the target field.
    | Tag | Description |
    | ------------------- | ----------------------------------------------------------------------------------------------------------------- |
    | `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 |
    | `FieldName` | Specifies a custom field name for copying when field names do not match between structs. |
  6. Copy data with custom `Option` using `CopyWithOption`

    master

    Use CopyWithOption when you need to control the copying behavior, such as enabling deep copies, ignoring empty values, or providing custom type converters.

    Common Option settings include:

    • IgnoreEmpty: If true, zero values of fields will be ignored.
    • DeepCopy: If true, performs a deep copy of the data.
    • CaseSensitive: If true, field name matching is case-sensitive.
    • Must: If true, all fields are treated as if they have the must tag.
    • NoPanic: If true, the program returns an error instead of panicking when a must field is not copied (only effective if Must is also true).
  7. Map field names between different types using `FieldNameMapping`

    master
    When the source and destination structs have different field names that aren't covered by tags, you can use FieldNameMapping within the Option struct to define a map of name translations for specific type pairs.
  8. Define custom `TypeConverter` for specific type mappings

    master

    If you need to copy data between types that aren't directly assignable or convertible, you can provide a TypeConverter.

    Each converter requires a SrcType and DstType (used as templates to identify the pair) and a Fn function that performs the actual conversion.

  9. Copy data between values with `Copy`

    master

    Use the Copy function to perform a basic copy from a source value (fromValue) to a destination value (toValue). This is useful for transferring data between different struct types, slices, or maps.

    Note that toValue must be a pointer or a type that can be addressed to allow the function to modify it.

  10. Reference Copier error definitions

    master

    The following error variables are exported by the copier package for error identification:

    var (
    	ErrInvalidCopyDestination        = errors.New("copy destination must be non-nil and addressable")
    	ErrInvalidCopyFrom               = errors.New("copy from must be non-nil and addressable")
    	ErrMapKeyNotMatch                = errors.New("map's key type doesn't match")
    	ErrNotSupported                  = errors.New("not supported")
    	ErrFieldNameTagStartNotUpperCase = errors.New("copier field name tag must be start upper case")
    )