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=value parameters

4. Process the Struct


car := Car{Doors: 5}
ok, err := checkTag.ProcessStruct(&car)

Processing performs the following steps:

  1. Optional Before() hook
  2. Directive execution for each tagged field
  3. Optional Success() hook
  4. 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() error
  • Success() error
  • Failure(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.