Hone logo
Hone
Problems

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 package declaration. 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 StructName and FieldName will 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 PackageName will be a valid Go identifier.
  • The generated source code string should not exceed 10KB.

Notes

  • Consider how you will parse the input Type strings 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/template or html/template packages 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.
Loading editor...
go