Go Code Generator for Simple Structs
This challenge asks you to build a Go program that generates Go source code for simple struct definitions. This is a foundational technique in software development, often used to automate the creation of boilerplate code, such as data models, API request/response structures, or database entities, saving significant development time and reducing errors.
Problem Description
Your task is to create a Go program that takes a structured description of a Go struct (its name and its fields) and outputs a valid Go source file containing that struct definition.
Requirements:
- Input: The program should accept input that describes the struct. This input could be in various formats (e.g., JSON, YAML, or a custom internal Go struct). For this challenge, we'll assume you'll define an internal Go struct to represent the input schema.
- Struct Definition: The generated code must define a Go struct with the specified name and fields.
- Field Types: Each field should have a name and a Go data type (e.g.,
string,int,bool,float64,[]string,map[string]int). - Package Declaration: The generated file must start with a
packagedeclaration. You should allow the user to specify the package name. - Imports: If the generated struct uses types from other packages (e.g.,
time.Time), the necessary import statements should be included. - Output: The program should output the generated Go source code as a string.
Expected Behavior:
Given a definition of a struct, the program should produce a syntactically correct Go source file that can be compiled.
Edge Cases to Consider:
- Structs with no fields.
- Fields with complex types (e.g., slices of custom types, maps with non-primitive keys/values). For this challenge, focus on primitive types, slices of primitives, and maps with primitive keys and values.
- Using standard library types that require imports (e.g.,
time.Time).
Examples
Example 1: Simple User Struct
Input Representation:
type InputStructDefinition struct {
PackageName string
StructName string
Fields []StructFieldDefinition
}
type StructFieldDefinition struct {
Name string
Type string // Go type string (e.g., "string", "int")
}
input := InputStructDefinition{
PackageName: "models",
StructName: "User",
Fields: []StructFieldDefinition{
{Name: "ID", Type: "int"},
{Name: "Username", Type: "string"},
{Name: "IsActive", Type: "bool"},
},
}
Output:
package models
type User struct {
ID int
Username string
IsActive bool
}
Explanation: The input describes a struct named User in the models package with three fields: ID (int), Username (string), and IsActive (bool). The output is a valid Go source code representation of this struct.
Example 2: Struct with Slice and Map
Input Representation:
input := InputStructDefinition{
PackageName: "data",
StructName: "Product",
Fields: []StructFieldDefinition{
{Name: "Name", Type: "string"},
{Name: "Tags", Type: "[]string"},
{Name: "PriceInfo", Type: "map[string]float64"},
},
}
Output:
package data
type Product struct {
Name string
Tags []string
PriceInfo map[string]float64
}
Explanation: The input describes a Product struct with a string name, a slice of strings for tags, and a map for price information. The generated code correctly reflects these types.
Example 3: Struct with Standard Library Type
Input Representation:
input := InputStructDefinition{
PackageName: "events",
StructName: "Order",
Fields: []StructFieldDefinition{
{Name: "OrderID", Type: "string"},
{Name: "CreatedAt", Type: "time.Time"},
},
}
Output:
package events
import "time"
type Order struct {
OrderID string
CreatedAt time.Time
}
Explanation: This example demonstrates handling a standard library type (time.Time). The generated code includes the necessary import "time" statement and the CreatedAt field of type time.Time.
Constraints
- The input
StructNameandFieldNamewill consist only of alphanumeric characters and underscores, starting with a letter. - Supported Go types for fields include:
string,int,int64,float32,float64,bool,[]string,[]int,[]float64,map[string]string,map[string]int,map[string]float64. - The program should handle at most 50 fields per struct.
- The
PackageNamewill be a valid Go identifier. - The generated source code string should not exceed 10KB.
Notes
- Consider how you will parse the input
Typestrings and map them to Go code representations. - Think about which standard library packages might be used by the supported field types and how to manage imports.
- You might want to use Go's built-in
text/templateorhtml/templatepackages for robust code generation, though string manipulation is also an option. - The goal is to produce syntactically correct Go code. You don't need to worry about generating functions or methods for these structs.