Automap: Automated mapping generation in Go

THIS PROJECT IS IN PROOF OF CONCEPT STAGE AND IS DEFINITELY
NOT SUITABLE FOR USE IN PRODUCTION
Automap is a code generation tool that automates creation of mappings between
different types. Resulting code operates without any additional runtime or
reflection, so it doesn't incur any runtime overhead compared to handwritten
mappings. Most of problems with generating mappings will happen at compile
time, unlike other automapping solutions based on reflection that tend to fail
at runtime. Finally, generated mappings are susceptible to code analysis tools
and can also be easily navigated manually.
This tool is heavily inspired by:
- Wire:
dependency injection framework for Go based on code generation
 
- AutoMapper:
convention-based object-object mapper in .NET
 
Installing
Install AutoMap by running:
go get github.com/skhoroshavin/automap/cmd/automap
and ensuring that $GOPATH/bin is added to your $PATH.
Quick start
Suppose you want to create a mapping from type User to UserDTO.
To do so first you need to create an automap.go file in your project with
the following contents:
//go:build automap
package mypackage
import "github.com/skhoroshavin/automap"
func UserToDTO(user *User) *UserDTO {
	panic(automap.Build())
}
Note that:
- it starts with build tag 
automap which prevents this file from compiling
during normal build process 
- it contains mapper function with desired signature
 
- implementation of that mapper function is just a stub which panics with the
result of marker function 
automap.Build() 
Then run automap tool in same directory which will create automap_gen.go
file with roughly following contents:
// Code generated by automap. DO NOT EDIT.
//go:build !automap
//go:generate automap
package mypackage
func UserToDTO(user *User) *UserDTO {
	return &UserDTO{
		FirstName: user.FirstName,
		LastName: user.LastName,   
	}
}
Note that:
- it starts with 
!automap build tag, so it doesn't interfere with subsequent
runs of this tool 
- it includes 
go:generate statement, so mappings can be updated just with
normal go generate calls, no need to explicitly run automap after first
bootstrapping 
- it doesn't import anything related to 
automap anymore 
- generated mapper has same signature as initial stub, and contains explicit
mapping of fields that have matching names
 
- if target type has fields that cannot be matched to any of inputs mapping
generation will fail - this will prevent accidentally creating incomplete
mappings
- Making this behaviour configurable (for example by somehow
providing custom mappings for such fields) is planned in future versions.