copygen

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2021 License: MIT Imports: 2 Imported by: 0

README

Copygen

GoDoc Go Report Card MIT License

Copygen is a command-line code generator that generates type-to-type and field-to-field struct code without adding any reflection or dependencies to your project.

Topic Categories
Use Types, YML, Command Line, Output
Customization Templates, Convert, Custom Options
Matcher Automatch
Optimization Shallow Copy vs. Deep Copy, Pointers
Benchmark

The benefit to using Copygen is performance: A benchmark by gotidy/copy shows that a manual copy is 391x faster than jinzhu/copier and 3.97x faster than the best reflection-based solution.

Use

Each example has a README.

Example Description
main The default example (README).
automatch Uses the automatch feature (doesn't require fields).
error Uses templates to return an error (temporarily unsupported).
deepcopy Uses templates to create a deepcopy.

This example uses three type-structs to generate the ModelsToDomain() function. All paths are specified from the types.yml filepath in examples/main.

Types

./domain/domain.go

// The domain package contains business logic models.
package domain

// Account represents a user account.
type Account struct {
	ID     int
	UserID string
	Name   string
	Other  string // The other field is not used.
}

./models/model.go

// The models package contains data storage models (i.e database).
package models

// Account represents the data model for account.
type Account struct {
	ID       int
	Name     string
	Password string
	Email    string
}

// A user represents the data model for a user.
type User struct {
	ID       int
	Name     int
	UserData string
}
YML

A YML file is used to configure the code that is generated. View Customization for an example using custom templates. Properties with # default are NOT necessary to include.

types.yml

# Define where the code will be generated.
generated:
  filepath: ./copygen.go
  package: copygen

# Define the imports that are included in the generated file.
import:
  - github.com/switchupcb/copygen/examples/main/domain
  - github.com/switchupcb/copygen/examples/main/models
  - github.com/switchupcb/copygen/examples/main/converter

# Define the functions to be generated.
# PROPERTIES WITH `# default` ARE NOT NECCESSARY TO INCLUDE.
functions:
 ModelsToDomain:

    # Custom function options can be defined for template use.
    options:                  # default: none
      custom: true

    # Define the types to be copied (to and from).
    to:
      Account:
        package:  domain      # default: none
        pointer:  true        # default: false     (# Optimization) 
  
        # Custom type options (to and from) can be defined for template use.
        options:              # default: none
          custom: false

    from:
      User:
        package: models       # default: none
        pointer: false        # default: false

        # Match fields to the to-type.
        fields:               # default: automatch (# Matcher)
          ID:
            to: UserID
            convert: c.Itoa   # default: none      (# Matcher)

            # Custom field options can be defined for template use.
            options:          # default: none
              custom: false

      Account:
        package: models       # default: none
        fields:
          ID:
            to: ID
          Name:
            to: Name

See Matcher or Optimization for information on respective properties.

Command Line

Install the command line utility (outside your project).

go install github.com/switchupcb/copygen

Run with given options.

# Specify the yml file.
copygen -yml path/to/yml

The path to the YML file is specified in reference to the current working directory.

Output

This example outputs a copygen.go file with the specified imports and functions.

// Code generated by github.com/switchupcb/copygen
// DO NOT EDIT.

package copygen

import (
	"github.com/switchupcb/copygen/examples/main/converter"
	"github.com/switchupcb/copygen/examples/main/domain"
	"github.com/switchupcb/copygen/examples/main/models"
)

// ModelsToDomain copies a User, Account to a Account.
func ModelsToDomain(tA *domain.Account, fU models.User, fA models.Account) {
	// Account fields
	tA.UserID = c.Itoa(fU.ID)
	tA.ID = fA.ID
	tA.Name = fA.Name

}
Customization

The error example modifies the .yml to use custom functions which return error. This is done by modifying the .yml and creating custom template files. All paths are specified from the types.yml file path in examples/error.

types.yml

# Define where the code will be generated.
generated:
  filepath: ./copygen.go
  package: copygen

  # Define the optional custom templates used to generate the file.
  templates:
    header: ./templates/header.go
    function: ./templates/function.go
Templates

Templates can be created using Go to customize the generated code. The copygen generator uses the package tenplates Header(*models.Generator) to generate header code and Function(*models.Function) to generate code for each function. As a result, these (package templates with functions) are required for your templates to work. View models.Generator and models.Function for context on the parameters passed to each function. Templates are interpreted by yaegi which has limitations on module imports (that are being fixed): As a result, templates are temporarily unsupported.

Convert

The convert property is used to specify a converter function. This is useful when you need to copy a value between two fields with different types, or provide another use-case. A default-template converter function uses the following signature:

func convert(f Field) Type {
    // implement custom function...
    return Type
}

where Field is replaced with the field it will receive (i.e int), and Type is replaced with the type it will return (i.e string).

Options

Function, Type, and Field custom options can be defined for template use. These are read into the respective models by yaml.

Matcher

Matching is specified in the .yml (which functions as a schema in relation to other generators). All from type-fields are assigned to respective to types. The library assumes that it's used with other code generators: This complicates the use of tags which is why they aren't used.

Automatch

If fields isn't specified for a from type, copygen will attempt to automatch type-fields by name. Automatch supports field-depth (where types are located within fields) and recursive types (where the same type is in another type). You must specify the import path for types that use the automatcher. Automatch loads types from Go modules (in GOPATH). Ensure your modules are up to date by using go get -u <insert/module/import/path>.

Depth

A depth level of 0 will match the first-level fields. Increasing the depth level will match more fields.

// depth level
type Account
  // 0
  ID      int
  Name    string
  Email   string
  Basic   domain.T // int
  User    domain.DomainUser
              // 1
              UserID   string
              Name     string
              UserData map[string]interface{}
  // 0
  Log     log.Logger
              // 1
              mu      sync.Mutex
                          // 2
                          state   int32
                          sema    uint32
              // 1
              prefix  string
              flag    int
              out     io.Writer
                          // 2
                          Write   func(p []byte) (n int, err error)
              buf     []byte

Optimization

Shallow Copy vs. Deep Copy

The library generates a shallow copy by default. An easy way to deep-copy fields with the same return type is by using new() as/in a converter function or by using a custom template.

Pointers

Go parameters are pass-by-value which means that a parameter's value (i.e int, memory address, etc) is copied into another location of memory. As a result, passing pointers to functions is more efficient if the byte size of a pointer is less than the total byte size of the struct member's references. However, be advised that doing so adds memory to the heap which can result in less performance. For more information regarding the use of pointers, read Pointers vs. Values in Parameters and Return Values. For more information on memory, read this article: What Every Programmer Should Know About Memory.

Contributing

You can contribute to this repository by viewing the Project Structure, Code Specifications, and Roadmap.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cli
generator/templates
Package templates provides a template used by copygen to generate custom code.
Package templates provides a template used by copygen to generate custom code.
loader
Package loader loads generator information from an external file.
Package loader loads generator information from an external file.
examples module
automatch/domain
Package domain contains business logic models.
Package domain contains business logic models.
automatch/models
Package models contains data storage models (i.e database).
Package models contains data storage models (i.e database).
error/converter
Package c provides custom converter functions used to copy types.
Package c provides custom converter functions used to copy types.
error/domain
Package domain contains business logic models.
Package domain contains business logic models.
error/models
Package models contains data storage models (i.e database).
Package models contains data storage models (i.e database).
error/templates
Package templates provides a template used by copygen to generate custom code.
Package templates provides a template used by copygen to generate custom code.
main/converter
Package c provides custom converter functions used to copy types.
Package c provides custom converter functions used to copy types.
main/domain
Package domain contains business logic models.
Package domain contains business logic models.
main/models
Package models contains data storage models (i.e database).
Package models contains data storage models (i.e database).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL