Skip to main content
Documentation

Attribute Reference

Supported built-in attributes, targets, and arguments.

Attributes precede the element they annotate. Use #[...] for definitions, fields, and cases, or #![...] for schema metadata. The attribute guide explains syntax.

JSON

TargetArgumentsMeaning
Opaque typetype = "...", schema = "..."JSON shape and optional JSON Schema reference
Recordrename_all = "..."Default field naming
Fieldname = "...", rename = "...", alias("..."), inlineExplicit name, naming convention, or inlined record
Variantrename_all = "...", tagged = ..., tag = "...", content = "..."Case naming and tagging
Variant casename = "...", rename = "...", content = "..."Case name and content field override

JSON shape names are number, boolean, string, null, object, array, and any. Combine them with |, as in "string|null".

Naming conventions are none, lowercase, UPPERCASE, camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, and SCREAMING-KEBAB-CASE.

Tagging values are unquoted paths: internally, adjacently, externally, and implicitly. Defaults are internal tagging, tag for the tag key, content for the payload key, camelCase record fields, and unchanged case names.

alias("oldName", "olderName") adds read-only keys to a record field. Lists accumulate across #[json(...)] attributes. Aliases are literal strings and do not undergo renaming. An alias must differ from the field’s main JSON name and every other name or alias in the flattened record, including an internal variant tag. Inline container fields and variant case names do not support aliases.

Rust’s native JSON decoder and Serde bridge, and Python’s Pydantic models, accept aliases. Serialization, JSON Schema, OpenAPI, and TypeScript types and checks use only the main name. Rust rejects input containing multiple spellings of one field; Python chooses the main name first, then aliases in declaration order.

An inline field merges the entries of its record into the surrounding object. It must be required, and its type must be a record or resolve to one through aliases and wrappers. JSON field names must be unique after renaming and flattening nested inline records, including the tag of an internally tagged variant. See JSON mapping for examples.

Rust

TargetArguments
Definitiontype = "...", derive(...), attr(...)
Fieldname = "...", pub, pub(crate), pub(super), private, box, arc, rc, wrap = "..."

Fields are public by default. pub and private cannot both apply to a field. Indirection attributes wrap the native field type without changing JSON shape. derive and attr arguments accumulate.

#[rust(derive(Clone, Debug), attr(non_exhaustive))]
record Profile {
    #[rust(private)]
    display_name: string,
}

A bare #[default] on a record field tells the Rust builder plugin to initialize it with Default::default() instead of adding it to the constructor arguments.

Python

#[py(typ = "module.Type")] maps an opaque definition to a native Python type:

#[json(type = "string")]
#[py(typ = "uuid.UUID")]
opaque UserId

The argument is named typ, while the Rust attribute uses type.

Validation

Targets are fields, records, wrappers, and opaque types. Each attribute contains one expression and optional message and code strings:

#[validate({ 1 <= _.size <= 64 }, message = "Use 1 to 64 characters.", code = "name:size")]

Repeat attributes for multiple rules. See validation for expression syntax, generator activation, and runtime limitations.

API Lifecycle

These attributes target definitions, fields, cases, and schemas:

AttributeArguments
deprecatedOptional since, remove_in, and note strings; may be bare
unstableOptional feature, note, and issue strings; may be bare
sinceRequired version string

See API lifecycle for lint behavior and migration examples.

Groups

group applies to definitions and requires name = "...", the name of a group declared in the manifest. An undeclared name is an error. Repeat the attribute to assign several groups, here assuming that the manifest declares mobile and web:

#[group(name = "mobile")]
#[group(name = "web")]
record CreateOrder {
    items: [OrderItem],
}

Definitions of the same bundle that a group member uses also belong to the group. See API groups for the membership rules.

Requests

request applies to a request definition and requires:

  • name = "...": wire request identifier.
  • response = Type: resolved response type reference.
#[request(name = "tasks.CreateTask", response = CreateTaskOutput)]
record CreateTask {
    title: string,
}

Define or import CreateTaskOutput in the same bundle. Request metadata explains how tools can consume this relationship.

Attribute Plugin Schemas

attrs and attr describe custom typed attribute plugins:

#[attrs(plugin = "ui", target = record, repeated)]
record UiRule {
    #[attr(name = "label")]
    display_label: string,
}

They are compiler extension metadata. See extending Sidex for discovery and generator integration.