Built-in templates
Metago embeds its standard templates in the binary. They work without local .metago files and use
the reserved std. namespace, which user templates cannot define.
| Template | Generates |
|---|---|
std.stringer | A String method for primitive-backed types. |
std.enum | String conversion, parsing, validation, values, and JSON for enums. |
std.mock | Function-backed mocks for interfaces. |
std.serde | Reflection-free JSON codecs. |
std.serde.jsonruntime | The shared runtime used by std.serde. |
std.stringer
Generate String() string for a primitive-backed defined type:
//mgo:gen std.stringer trimprefix=Status
type Status int
const (
StatusPending Status = iota
StatusRunning
StatusDone
)
When the type has declared typed constants, they become switch cases:
func (v Status) String() string {
switch v {
case StatusPending:
return "Pending"
case StatusRunning:
return "Running"
case StatusDone:
return "Done"
default:
return "Status(" + strconv.FormatInt(int64(v), 10) + ")"
}
}
Supported underlying types are string, bool, signed and unsigned integers, floats, and complex
numbers. For types with constants, unknown values use Type(value) and unknown strings are quoted.
For ordinary value types without constants, String returns the underlying value’s standard text
representation directly (for example, UserID(42).String() returns "42").
| Argument | Default | Behavior |
|---|---|---|
trimprefix=value | No trimming | Removes the prefix from constant names returned by String. |
The target must be primitive-backed. Other targets fail generation.
std.enum
Generate the conventional enum API from a defined type and its typed constants:
//mgo:gen std.enum
type Status int
const (
StatusPending Status = iota
StatusRunning
StatusDone
)
The generated API is:
func (v Status) String() string
func ParseStatus(value string) (Status, error)
func (v Status) Valid() bool
func StatusValues() []Status
func (v Status) MarshalJSON() ([]byte, error)
func (v *Status) UnmarshalJSON(data []byte) error
Supported underlying types are strings, signed integers, unsigned integers, and floats. The type must have at least one discovered typed constant.
Integer and float enums strip the type name from constant names by default. String enums use each constant’s string value. JSON uses the same string form and rejects unknown values.
| Argument | Default | Behavior |
|---|---|---|
trimprefix=value | The target type name | Changes the prefix removed from integer and float constant names. |
std.mock
Generate a function-backed mock for an interface:
//mgo:gen std.mock
type Store interface {
Get(id string) (User, error)
Save(user User) error
}
The generated mock has one function field per discovered method and forwarding methods that satisfy the interface:
type MockStore struct {
GetFunc func(id string) (User, error)
SaveFunc func(user User) error
}
func (m *MockStore) Get(id string) (User, error) {
return m.GetFunc(id)
}
func (m *MockStore) Save(user User) error {
return m.SaveFunc(user)
}
Assign the function fields directly in tests:
store := &MockStore{
GetFunc: func(id string) (User, error) {
return User{ID: id}, nil
},
SaveFunc: func(user User) error {
return nil
},
}
Interface method parameters should be named. Embedded interface methods are not expanded, and variadic forwarding is not specially handled.
std.serde
Generate reflection-free MarshalJSON and UnmarshalJSON methods:
//mgo:gen std.serde
type User struct {
ID int64 `json:"id"`
Name string `json:"name"`
Tags []string `json:"tags,omitempty"`
}
Generated paths cover built-in and methodless named scalars, pointers, slices, arrays, bytes,
json.RawMessage, string-keyed maps, nested generated types, and common combinations of those
shapes.
Unsupported fields use encoding/json and continue to support json.Marshaler, json.Unmarshaler,
encoding.TextMarshaler, and encoding.TextUnmarshaler. Structs containing anonymous fields use
encoding/json for the complete struct.
Serde follows encoding/json behavior for field names and visibility, -, omitempty, omitzero,
and supported string options. Decode failures are transactional, and retained decoded strings do
not alias the input. Recursive generated pointers and containers detect cycles during encoding.
Errors include field, Go type, JSON kind, and offset context.
| Argument | Default | Behavior |
|---|---|---|
runtime=import/path | Same package | Imports the generated runtime from this path. |
strict=true|false | false | Rejects unknown object fields when true. Otherwise unknown values are skipped after full syntax validation. |
maxinput=N | Disabled | Rejects input larger than N bytes before receiver-state allocation. Zero disables the cap. |
maxdepth=N | 10000 | Sets the maximum JSON nesting depth. Zero keeps the default. |
strict accepts only true or false. maxinput and maxdepth must be unsigned 64-bit decimal
integers. Invalid values fail generation. Directive-local arguments override defaults from
metago.toml.
Without a runtime argument, codecs expect std.serde.jsonruntime in the same package. To use a
dedicated runtime package, configure its import path:
[templates."std.serde".args]
runtime = "example.com/project/internal/jsonruntime"
std.serde.jsonruntime
Generate the shared runtime once in the configured package:
// Package jsonruntime contains generated JSON support.
//
//mgo:gen std.serde.jsonruntime
package jsonruntime
Every package sharing this runtime must use the same configured path.
For compatibility policy, reliability tests, and benchmarks, see the
std/serde implementation notes.