Getting Started
Tagex is a Go library for executing typed logic based on struct tags.
You define directives — small, focused pieces of Go code — register them under a tag key, and then apply them to struct fields using standard Go struct tags.
The Mental Model
Tagex has four core concepts:
- Tag — a processing context, identified by a struct tag key
- Directive — typed logic applied to a field
- Parameters — values mapped into the directive
- Processing — walking a struct and executing directives
Nothing is implicit: every directive is registered explicitly, parameters are mapped explicitly, and execution order is deterministic.
1. Define a Directive
A directive is a struct that implements tagex.Directive[T],
where T is the field type it operates on.
type RangeDirective struct {
Min int `param:"min"`
Max int `param:"max"`
}
func (d *RangeDirective) Name() string {
return "range"
}
func (d *RangeDirective) Mode() tagex.DirectiveMode {
return tagex.EvalMode
}
func (d *RangeDirective) Handle(val int) (int, error) {
if val < d.Min || val > d.Max {
return val, fmt.Errorf("value %d out of range", val)
}
return val, nil
}
The param tags tell Tagex which directive fields should
receive values from the struct tag.
2. Create a Tag Context
A Tag represents a processing environment for a single
struct tag key.
checkTag := tagex.NewTag("check")
tagex.RegisterDirective(&checkTag, &RangeDirective{})
Directives are registered by name and are looked up when processing struct fields.
3. Annotate a Struct
type Car struct {
Doors int `check:"range, min=2, max=4"`
}
The tag format is:
key:"directive, param=value, ..."
- The first element selects the directive
- Remaining elements are
key=valueparameters
4. Process the Struct
car := Car{Doors: 5}
ok, err := checkTag.ProcessStruct(&car)
Processing performs the following steps:
- Optional
Before()hook - Directive execution for each tagged field
- Optional
Success()hook - Optional
Failure(err)hook when processing fails
Evaluation is short-circuiting: the first error stops processing.
Evaluation vs Mutation
Directives can either:
- Evaluate a field (
EvalMode) - Mutate a field (
MutMode)
In mutation mode, the value returned from Handle is written
back to the struct field.
Pre and Post Processing
If the target struct implements:
Before() errorSuccess() errorFailure(err error) error
These hooks are invoked automatically around directive execution.
Next Steps
- Writing mutating directives
- Custom parameter converters
- Error handling and composition
- Designing reusable directive libraries
These topics are covered in the Guides section.