A Go code generator for creating polymorphic data structures with JSON serialization support.
Given the following Go code:
type IsItem interface {
isItem()
}
type TextItem struct {
Content string `json:"content"`
}
func (TextItem) isItem() {}
type ImageItem struct {
URL string `json:"url"`
}
func (*ImageItem) isItem() {}
Create a .polygen.json
file in your project root:
{
"$schema": "https://raw.githubusercontent.com/ykalchevskiy/polygen/refs/tags/v0.0.6/schema.json",
"types": [
{
"type": "Item",
"interface": "IsItem",
"package": "main",
"subtypes": {
"TextItem": {
"name": "text"
},
"ImageItem": {
"name": "image",
"pointer": true
}
}
}
]
}
Then run:
polygen
The generated code allows you to marshal/unmarshal your types to/from JSON:
// unmarshaling
var item Item
json.Unmarshal([]byte(`{"type": "text", "content": "hello"}`), &item)
json.Unmarshal([]byte(`{"content": "updated"}`), &item) // Updates just content
json.Unmarshal([]byte(`{"type": "image", "url": "pic.jpg"}`), &item) // Changes type
// marshaling
json.Marshal(Item{IsItem: TextItem{Content: "Hello, World!"}})
// {"type": "text", "content": "Hello, World!"}
json.Marshal(Item{IsItem: &ImageItem{URL: "https://example.com/image.jpg"}})
// {"type": "image", "url": "https://example.com/image.jpg"}
go install github.com/ykalchevskiy/polygen@latest
The JSON configuration file supports:
- Multiple type definitions in a single file
- Global and per-type discriminator field name
- Global and per-type strict mode settings
- Global and per-subtype pointer mode settings
- Custom output paths relative to config file
The configuration follows this structure:
strictByDefault
(optional): Enable strict mode by defaultpointerByDefault
(optional): Mark all subtypes as pointer mode by defaultdefaultDiscriminator
(optional): Default JSON field name for type discrimination (default: "type")types
(required): Array of type configurations:type
(required): Name of the polymorphic structureinterface
(required): Name of the interface all subtypes implementpackage
(required): Package name for generated codediscriminator
(optional): Override default JSON field namedirectory
(optional): Output directory path relative to config filefilename
(optional): Output filename (defaults to _polygen.go)strict
(optional): Override strict mode for this typedefaultSubtype
(optional): Default subtype to unmarshal into when the discriminator field is missingsubtypes
(required): Map of Go type names to their configurations:name
(optional): JSON type name (defaults to subtype name in kebab-case)pointer
(optional): Use pointer for this type (defaults topointerByDefault
)