Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Go Cookbook

Practical, copy-paste-ready recipes for Go code generation. For the full API of each spec type, see Building Functions & Fields, Building Types & Enums, and Files & Projects.

Struct with tags

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("User", TypeKind::Struct)
    .add_field(
        FieldSpec::builder("Name", TypeName::primitive("string"))
            .tag("json:\"name\" db:\"name\"")
            .build()
            .unwrap(),
    )
    .add_field(
        FieldSpec::builder("Email", TypeName::primitive("string"))
            .tag("json:\"email\" db:\"email\"")
            .build()
            .unwrap(),
    )
    .add_field(
        FieldSpec::builder("Age", TypeName::primitive("int"))
            .tag("json:\"age,omitempty\"")
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();
type User struct {
    Name string `json:"name" db:"name"`
    Email string `json:"email" db:"email"`
    Age int `json:"age,omitempty"`
}

Newtype (distinct type)

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("Meters", TypeKind::Newtype)
    .extends(TypeName::primitive("float64"))
    .build()
    .unwrap();
type Meters float64

Interface

use sigil_stitch::prelude::*;

let type_spec = TypeSpec::builder("Repository", TypeKind::Interface)
    .doc("Repository defines data access methods.")
    .add_method(
        FunSpec::builder("FindByID")
            .add_param(ParameterSpec::new("id", TypeName::primitive("string")).unwrap())
            .returns(TypeName::raw("(Entity, error)"))
            .build()
            .unwrap(),
    )
    .add_method(
        FunSpec::builder("Save")
            .add_param(ParameterSpec::new("entity", TypeName::primitive("Entity")).unwrap())
            .returns(TypeName::primitive("error"))
            .build()
            .unwrap(),
    )
    .build()
    .unwrap();

let file = FileSpec::builder("repo.go")
    .header(CodeBlock::of("package repo", ()).unwrap())
    .add_type(type_spec)
    .build()
    .unwrap();
let output = file.render(80).unwrap();
package repo

// Repository defines data access methods.
type Repository interface {
	FindByID(id string) (Entity, error)

	Save(entity Entity) error
}

Generic function

use sigil_stitch::prelude::*;

let tp = TypeParamSpec::new("T").with_bound(TypeName::primitive("comparable"));

let mut body_b = CodeBlock::builder();
body_b.begin_control_flow("if a > b", ());
body_b.add_statement("return a", ());
body_b.end_control_flow();
body_b.add_statement("return b", ());
let body = body_b.build().unwrap();

let fun = FunSpec::builder("Max")
    .add_type_param(tp)
    .add_param(ParameterSpec::new("a", TypeName::primitive("T")).unwrap())
    .add_param(ParameterSpec::new("b", TypeName::primitive("T")).unwrap())
    .returns(TypeName::primitive("T"))
    .body(body)
    .build()
    .unwrap();

let file = FileSpec::builder("max.go")
    .header(CodeBlock::of("package main", ()).unwrap())
    .add_function(fun)
    .build()
    .unwrap();
let output = file.render(80).unwrap();
package main

func Max[T comparable](a T, b T) T {
	if a > b {
		return a
	}
	return b
}