automapper

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2026 License: MIT Imports: 0 Imported by: 0

README

automapper

A CLI tool that automatically generates struct-to-struct mapping code for Go.

Concept: "Auto-map same name & type, tag only the exceptions"

Installation

go install github.com/mickamy/automapper/cmd/automapper

Basic Usage

# One-way mapping (User -> UserPB)
automapper -from=model.User -to=pb.UserPB

# Bidirectional mapping (User <-> UserPB)
automapper -types=model.User:pb.UserPB

# Custom output directory (default: ./amgen)
automapper -from=model.User -to=pb.UserPB -output=./mappers

# Specify package containing custom converters
automapper -from=model.User -to=pb.UserPB -converter-pkg=./converters

Usage with go:generate

//go:generate automapper -types=model.User:pb.UserPB

Generated Code

// amgen/user.gen.go
package amgen

// Pointer version
func ToPbUserPBPtr(src *model.User) *pb.UserPB { ... }

// Value version
func ToPbUserPB(src model.User) pb.UserPB { ... }

// Reverse mapping (when using -types for bidirectional)
func FromPbUserPBPtr(src *pb.UserPB) *model.User { ... }
func FromPbUserPB(src pb.UserPB) model.User { ... }
When Converters Return Errors

If any registered converter returns an error (e.g., RegisterFromE), the generated function also returns an error:

// Generated when using error-returning converters
func FromPbUserPBPtr(src *pb.UserPB) (*model.User, error) {
    if src == nil {
        return nil, nil
    }
    birthDate, err := converters.FromDate(src.BirthDate)
    if err != nil {
        return nil, fmt.Errorf("BirthDate: %w", err)
    }
    return &model.User{
        ID:        src.Id,
        Name:      src.Name,
        BirthDate: birthDate,
    }, nil
}

func FromPbUserPB(src pb.UserPB) (model.User, error) {
    birthDate, err := converters.FromDate(src.BirthDate)
    if err != nil {
        return model.User{}, fmt.Errorf("BirthDate: %w", err)
    }
    return model.User{
        ID:        src.Id,
        Name:      src.Name,
        BirthDate: birthDate,
    }, nil
}

Mapping Rules

Priority Rule Description
1 map:"-" Ignore field
2 map:"TargetName" Map to specified field name
3 map:",conv=name" Use named converter
4 Same name & type Direct copy
5 Same name, different type Look for registered converter
6 Target only Ignore (zero value)
7 Unexported Ignore

Tag Examples

type User struct {
    ID        int64     `map:"UserId"`           // Rename to UserId
    Password  string    `map:"-"`                // Ignore
    CreatedAt time.Time `map:",conv=timeToUnix"` // Use named converter
}

Custom Converters

Type-based Converters

Converters are automatically matched by type pair.

package converters

import (
	"strconv"
	"time"
	
	"github.com/mickamy/automapper"
)

func init() {
    // time.Time -> int64
    automapper.RegisterTo[time.Time, int64](TimeToUnix)

    // int64 -> time.Time
    automapper.RegisterFrom[int64, time.Time](UnixToTime)

    // Converter that returns error
    automapper.RegisterToE[string, int](strconv.Atoi)
}

func TimeToUnix(t time.Time) int64 {
    return t.Unix()
}

func UnixToTime(ts int64) time.Time {
    return time.Unix(ts, 0)
}
Named Converters

Use when you need to explicitly specify a converter via tag.

func init() {
    // Referenced by map:",conv=priceToInt"
    automapper.RegisterToNamed[string, int64]("priceToInt", PriceStringToCents)

    // Named converter that returns error
    automapper.RegisterFromNamedE[int64, string]("priceFromInt", CentsToPriceString)
}

func PriceStringToCents(s string) int64 {
    // "$19.99" -> 1999
    ...
}

func CentsToPriceString(cents int64) (string, error) {
    // 1999 -> "$19.99"
    ...
}

Usage:

type Product struct {
    Price string `map:",conv=priceToInt"` // Use named converter
}

Register API

Function Description
RegisterTo[A, B](fn func(A) B) Register A → B converter
RegisterFrom[A, B](fn func(A) B) Register A → B converter
RegisterToE[A, B](fn func(A) (B, error)) A → B with error
RegisterFromE[A, B](fn func(A) (B, error)) A → B with error
RegisterToNamed[A, B](name, fn) Named A → B
RegisterFromNamed[A, B](name, fn) Named A → B
RegisterToNamedE[A, B](name, fn) Named A → B with error
RegisterFromNamedE[A, B](name, fn) Named A → B with error

CLI Flags

Flag Description Default
-from Source type (e.g., model.User) -
-to Target type (e.g., pb.UserPB) -
-types Bidirectional type pair (e.g., User:UserPB) -
-output Output directory ./amgen
-converter-pkg Package containing converters -
-version Show version -

License

MIT

Documentation

Overview

Package automapper provides struct-to-struct mapping code generation. Users register custom converters that the CLI uses during code generation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterFrom

func RegisterFrom[A, B any](fn func(A) B)

RegisterFrom registers a converter function from type A to type B. The type parameter order is [source, dest], same as RegisterTo.

Example:

func init() {
    automapper.RegisterFrom[int64, time.Time](UnixToTime)
}

func RegisterFromE

func RegisterFromE[A, B any](fn func(A) (B, error))

RegisterFromE registers a converter function from type A to type B that may return an error. The type parameter order is [source, dest], same as RegisterToE.

Example:

func init() {
    automapper.RegisterFromE[string, time.Time](RFC3339ToTime)
}

func RegisterFromNamed

func RegisterFromNamed[A, B any](name string, fn func(A) B)

RegisterFromNamed registers a named converter function from type A to type B. The type parameter order is [source, dest], same as RegisterToNamed.

Example:

func init() {
    automapper.RegisterFromNamed[int64, string]("rfc3339", RFC3339ToTime)
}

func RegisterFromNamedE

func RegisterFromNamedE[A, B any](name string, fn func(A) (B, error))

RegisterFromNamedE registers a named converter function from type A to type B that may return an error. The type parameter order is [source, dest], same as RegisterToNamedE.

Example:

func init() {
    automapper.RegisterFromNamedE[int64, string]("rfc3339", RFC3339ToTimeE)
}

func RegisterTo

func RegisterTo[A, B any](fn func(A) B)

RegisterTo registers a converter function from type A to type B. The converter is called when generating mapping code where the source field is type A and target field is type B.

Example:

func init() {
    automapper.RegisterTo[time.Time, *datepb.Date](ToDate)
}

func RegisterToE

func RegisterToE[A, B any](fn func(A) (B, error))

RegisterToE registers a converter function from type A to type B that may return an error.

Example:

func init() {
    automapper.RegisterToE[string, int](strconv.Atoi)
}

func RegisterToNamed

func RegisterToNamed[A, B any](name string, fn func(A) B)

RegisterToNamed registers a named converter function from type A to type B. Named converters can be referenced in struct tags using map:",conv=name".

Example:

func init() {
    automapper.RegisterToNamed[time.Time, string]("rfc3339", TimeToRFC3339)
}

func RegisterToNamedE

func RegisterToNamedE[A, B any](name string, fn func(A) (B, error))

RegisterToNamedE registers a named converter function from type A to type B that may return an error.

Example:

func init() {
    automapper.RegisterToNamedE[time.Time, string]("rfc3339", TimeToRFC3339E)
}

Types

This section is empty.

Directories

Path Synopsis
cmd
automapper command
Package main provides the automapper CLI.
Package main provides the automapper CLI.
internal
analyzer
Package analyzer provides AST analysis for struct types and converter registrations.
Package analyzer provides AST analysis for struct types and converter registrations.
generator
Package generator produces Go source code for struct mappers.
Package generator produces Go source code for struct mappers.
registry
Package registry manages converter registrations for code generation.
Package registry manages converter registrations for code generation.
resolver
Package resolver determines field mappings between struct types.
Package resolver determines field mappings between struct types.

Jump to

Keyboard shortcuts

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