Generator of various enumerated constants, types, functions based on a type properties like name, structure fields, tags or base type nature.
-
fields-to-consts - generate constants based on template applied to struct fields.
-
get-set - generates getters, setters for a structure type.
-
builder - generates builder API of a structure type.
-
as-map - generates a method or functon that converts the struct type to a map.
-
enrich-const-type - extends a constants type by 'get name' method, 'enum all values' function and 'get a constant by a value of the underlying type' function.
go install github.com/m4gshm/fieldr@latest
or
go install github.com/m4gshm/fieldr@HEAD
source entity.go
:
package enum_const
//go:generate fieldr -type Entity fields-to-consts -val tag.json -list jsons
type Entity struct {
Id int `json:"id"`
Name string `json:"name"`
}
then running this command in the same directory:
go generate .
will be generated entity_fieldr.go
file with the next content:
// Code generated by 'fieldr'; DO NOT EDIT.
package enum_const
const (
entityJsonId = "id"
entityJsonName = "name"
)
func jsons() []string {
return []string{entityJsonId, entityJsonName}
}
this consist of constants based on the json
tag contents and the
method jsons
that enumerates these constants.
To get extended help of the command, use the following:
fieldr fields-to-consts help
source entity.go
:
package enum_const_db
//go:generate fieldr -type Entity
//go:fieldr fields-to-consts -name "'col' + field.name" -val "tag.db" -flat Versioned -type column -list . -ref-access .
//go:fieldr fields-to-consts -name "'pk' + field.name" -val "tag.db" -include "tag.pk != nil" -type column -list pk
type Entity struct {
BaseEntity
Versioned *VersionedEntity
Name string `db:"name"`
}
type BaseEntity struct {
ID int32 `db:"id" pk:""`
}
type VersionedEntity struct {
Version int64 `db:"version"`
}
generated entity_fieldr.go
:
// Code generated by 'fieldr'; DO NOT EDIT.
package enum_const_db
type column string
const (
colID column = "id"
colVersion column = "version"
colName column = "name"
pkID column = "id"
)
func columns() []column {
return []column{colID, colVersion, colName}
}
func (s *Entity) ref(f column) any {
if s == nil {
return nil
}
switch f {
case colID:
return &s.BaseEntity.ID
case colVersion:
if v := s.Versioned; v != nil {
return &v.Version
}
case colName:
return &s.Name
}
return nil
}
func pk() []column {
return []column{pkID}
}
-
-name "'col' + field.name" - defines constant names as 'col' appended by the associated field name.
-
-val "tag.db" - defines the value of a constant as a copy of the
db
tag of the associated field name. -
-flat Versioned - also uses the
VersionedEntity
fields as constants source type in addition to the baseEntity
type. -
-type column - adds the
column
type, and uses it as the type of the generated constants. -
-list . - generates the
columns
function that returns constant values. It can be used to build sql queries like INSERT, SELECT. -
-ref-access . - generates the
ref
method that provides access to the filed values, returns a reference pointing to the field associated with the constant. The method can be used in conjunction with Row.Scan from sql package. -
-include "tag.pk != nil" - uses only 'pk' tag having a value.
source entity.go
package get_set
import "time"
//go:generate fieldr -type Entity get-set
type BaseEntity[ID any] struct {
id ID
}
type Entity[ID any] struct {
*BaseEntity[ID]
name string
surname string
ts time.Time
}
go generate .
generates entity_fieldr.go
// Code generated by 'fieldr'; DO NOT EDIT.
package get_set
import "time"
func (e *Entity[ID]) Id() ID {
if e != nil {
if be := e.BaseEntity; be != nil {
return be.id
}
}
var no ID
return no
}
func (e *Entity[ID]) SetId(id ID) {
if e != nil {
if be := e.BaseEntity; be != nil {
be.id = id
}
}
}
func (e *Entity[ID]) Name() string {
if e != nil {
return e.name
}
var no string
return no
}
func (e *Entity[ID]) SetName(name string) {
if e != nil {
e.name = name
}
}
func (e *Entity[ID]) Surname() string {
if e != nil {
return e.surname
}
var no string
return no
}
func (e *Entity[ID]) SetSurname(surname string) {
if e != nil {
e.surname = surname
}
}
func (e *Entity[ID]) Ts() time.Time {
if e != nil {
return e.ts
}
var no time.Time
return no
}
func (e *Entity[ID]) SetTs(ts time.Time) {
if e != nil {
e.ts = ts
}
}
source entity.go
package builder
//go:generate fieldr -type Entity builder -deconstructor .
type Entity[ID any] struct {
*Model[ID]
Name string
}
type Model[ID any] struct {
ID ID
CreatedAt int64
UpdatedAt int64
}
go generate .
generates entity_fieldr.go
// Code generated by 'fieldr'; DO NOT EDIT.
package builder
type EntityBuilder[ID any] struct {
iD ID
createdAt int64
updatedAt int64
name string
}
func NewEntityBuilder[ID any]() *EntityBuilder[ID] {
return &EntityBuilder[ID]{}
}
func (b *EntityBuilder[ID]) Build() *Entity[ID] {
if b == nil {
return &Entity[ID]{}
}
return &Entity[ID]{
Model: &Model[ID]{
ID: b.iD,
CreatedAt: b.createdAt,
UpdatedAt: b.updatedAt,
},
Name: b.name,
}
}
func (b *EntityBuilder[ID]) ID(iD ID) *EntityBuilder[ID] {
if b != nil {
b.iD = iD
}
return b
}
func (b *EntityBuilder[ID]) CreatedAt(createdAt int64) *EntityBuilder[ID] {
if b != nil {
b.createdAt = createdAt
}
return b
}
func (b *EntityBuilder[ID]) UpdatedAt(updatedAt int64) *EntityBuilder[ID] {
if b != nil {
b.updatedAt = updatedAt
}
return b
}
func (b *EntityBuilder[ID]) Name(name string) *EntityBuilder[ID] {
if b != nil {
b.name = name
}
return b
}
func (e *Entity[ID]) ToBuilder() *EntityBuilder[ID] {
if e == nil {
return &EntityBuilder[ID]{}
}
var (
Model_ID ID
Model_CreatedAt int64
Model_UpdatedAt int64
)
if m := e.Model; m != nil {
Model_ID = m.ID
Model_CreatedAt = m.CreatedAt
Model_UpdatedAt = m.UpdatedAt
}
return &EntityBuilder[ID]{
iD: Model_ID,
createdAt: Model_CreatedAt,
updatedAt: Model_UpdatedAt,
name: e.Name,
}
}
source struct.go
package asmap
import "time"
//go:generate fieldr -type EmbeddedAddress -out address_as_map.go as-map -key-type . -export
//go:generate fieldr -type Struct -out struct_as_map.go as-map -key-type . -export -rewrite type:*EmbeddedAddress:fmt=%v.AsMap() -flat Flat
type BaseStruct struct {
ID int
TS *time.Time
}
type EmbeddedAddress struct {
ZipCode int
AddressLine string
}
type FlatPart struct {
CardNum string
Bank string
}
type Struct[n string] struct {
*BaseStruct
Name n
Surname string
noExport string //nolint
NoTag string
Address *EmbeddedAddress
Flat FlatPart
}
go generate .
generates two files struct_as_map.go
, address_as_map.go
// Code generated by 'fieldr'; DO NOT EDIT.
package asmap
type StructField string
const (
BaseStructID StructField = "ID"
BaseStructTS StructField = "TS"
Name StructField = "Name"
Surname StructField = "Surname"
NoTag StructField = "NoTag"
Address StructField = "Address"
FlatCardNum StructField = "CardNum"
FlatBank StructField = "Bank"
)
func (s *Struct[n]) AsMap() map[StructField]any {
if s == nil {
return nil
}
m := map[StructField]any{}
if bs := s.BaseStruct; bs != nil {
m[BaseStructID] = bs.ID
}
if bs := s.BaseStruct; bs != nil {
if ts := bs.TS; ts != nil {
m[BaseStructTS] = ts
}
}
m[Name] = s.Name
m[Surname] = s.Surname
m[NoTag] = s.NoTag
if a := s.Address; a != nil {
m[Address] = a.AsMap()
}
m[FlatCardNum] = s.Flat.CardNum
m[FlatBank] = s.Flat.Bank
return m
}
// Code generated by 'fieldr'; DO NOT EDIT.
package asmap
type EmbeddedAddressField string
const (
ZipCode EmbeddedAddressField = "ZipCode"
AddressLine EmbeddedAddressField = "AddressLine"
)
func (e *EmbeddedAddress) AsMap() map[EmbeddedAddressField]any {
if e == nil {
return nil
}
m := map[EmbeddedAddressField]any{}
m[ZipCode] = e.ZipCode
m[AddressLine] = e.AddressLine
return m
}
source enum.go
package enrich_enum
//go:generate fieldr -type Enum enrich-const-type -export
type Enum int
const (
AA Enum = iota + 1
BB
CC
DD
)
//go:generate fieldr -type StringEnum enrich-const-type -export
type BaseStringEnum string
type StringEnum BaseStringEnum
const (
FIRST StringEnum = "first one"
SECOND StringEnum = "one more"
THIRD StringEnum = "any third"
)
go generate .
generates enum_fieldr.go
// Code generated by 'fieldr'; DO NOT EDIT.
package enrich_enum
func (e Enum) Name() string {
switch e {
case AA:
return "AA"
case BB:
return "BB"
case CC:
return "CC"
case DD:
return "DD"
default:
return ""
}
}
func EnumAll() []Enum {
return []Enum{
AA,
BB,
CC,
DD,
}
}
func EnumByName(name string) (e Enum, ok bool) {
ok = true
switch name {
case "AA":
e = AA
case "BB":
e = BB
case "CC":
e = CC
case "DD":
e = DD
default:
ok = false
}
return
}
func EnumByValue(value int) (e Enum, ok bool) {
ok = true
switch value {
case 1:
e = AA
case 2:
e = BB
case 3:
e = CC
case 4:
e = DD
default:
ok = false
}
return
}
and stringenum_fieldr.go
// Code generated by 'fieldr'; DO NOT EDIT.
package enrich_enum
func (s StringEnum) Name() string {
switch s {
case FIRST:
return "FIRST"
case SECOND:
return "SECOND"
case THIRD:
return "THIRD"
default:
return ""
}
}
func StringEnumAll() []StringEnum {
return []StringEnum{
FIRST,
SECOND,
THIRD,
}
}
func StringEnumByName(name string) (e StringEnum, ok bool) {
ok = true
switch name {
case "FIRST":
e = FIRST
case "SECOND":
e = SECOND
case "THIRD":
e = THIRD
default:
ok = false
}
return
}
func StringEnumByValue(value string) (e StringEnum, ok bool) {
ok = true
switch value {
case "first one":
e = FIRST
case "one more":
e = SECOND
case "any third":
e = THIRD
default:
ok = false
}
return
}
See more examples here