#[repr(u8)]pub enum Attr {
Show 40 variants
Sensitive,
Opaque,
Transparent,
MetadataContainer,
Flatten,
Trailing,
Child,
DenyUnknownFields,
Default(Option<DefaultInPlaceFn>),
Skip,
SkipSerializing,
SkipSerializingIf(Option<SkipSerializingIfFn>),
SkipUnlessTruthy,
SkipDeserializing,
Untagged,
Other,
IsNumeric,
Cow,
Pod,
Rename(&'static str),
RenameAll(&'static str),
Alias(&'static str),
Tag(Option<&'static str>),
Content(Option<&'static str>),
TypeTag(&'static str),
Invariants(Option<InvariantsFn>),
Truthy(Option<TruthyFn>),
SkipAllUnlessTruthy,
Proxy(&'static Shape),
RecursiveType,
Where(&'static str),
Traits(&'static str),
AutoTraits,
Metadata(&'static str),
Crate(&'static str),
FromRef,
TryFromRef,
Attribute,
Text,
CustomElement,
}Expand description
Built-in facet attribute types.
These represent the runtime-queryable built-in attributes. Attributes with function pointers store the actual function reference.
Attributes annotated with #[storage(flag)] are stored in FieldFlags for O(1) access.
Attributes annotated with #[storage(field)] are stored in dedicated Field struct fields.
Attributes without #[storage(...)] are stored in the attributes slice (O(n) lookup).
https://facet.rs/guide/attributes/
Variants§
Sensitive
Marks a field as containing sensitive data that should be redacted in debug output.
Usage: #[facet(sensitive)]
Opaque
Marks a container as opaque - its inner fields don’t need to implement Facet.
Usage: #[facet(opaque)]
Transparent
Marks a container as transparent - de/serialization is forwarded to the inner type. Used for newtype patterns.
Usage: #[facet(transparent)]
MetadataContainer
Marks a struct as a metadata container - it serializes transparently through its non-metadata field while preserving metadata for formats that support it.
Rules:
- Exactly one non-metadata field (the “value” field)
- At least one metadata field (marked with
#[facet(metadata = "...")]) - No duplicate metadata kinds
During serialization, the container is transparent - Documented<String> serializes
exactly like String. However, formats that support metadata (like Styx) can access
the metadata fields and emit them appropriately (e.g., as doc comments).
Usage: #[facet(metadata_container)]
§Example
#[derive(Facet)]
#[facet(metadata_container)]
struct Documented<T> {
value: T,
#[facet(metadata = "doc")]
doc: Option<Vec<String>>,
}Flatten
Marks a field to be flattened into its parent structure.
Usage: #[facet(flatten)]
Trailing
Marks an opaque payload field as structurally trailing in its container.
This enables formats that support it to treat the field as “remaining bytes” instead of requiring an outer length frame.
Usage: #[facet(trailing)]
Child
Marks a field as a child node (for hierarchical formats like XML).
Usage: #[facet(child)]
DenyUnknownFields
Denies unknown fields during deserialization.
Usage: #[facet(deny_unknown_fields)]
Default(Option<DefaultInPlaceFn>)
Uses the default value when the field is missing during deserialization. Stores a function pointer that produces the default value in-place.
Usage: #[facet(default)] (uses Default trait) or #[facet(default = expr)]
When no explicit value is given (#[facet(default)]), the Rust field type’s
Default::default() is used. This requires the field type to implement Default.
For opaque fields, this uses the underlying Rust type’s Default, not the
Facet shape’s default.
Note: The HAS_DEFAULT flag is also set when this attribute is present.
Skip
Skips both serialization and deserialization of this field.
Usage: #[facet(skip)]
SkipSerializing
Skips serialization of this field.
Usage: #[facet(skip_serializing)]
SkipSerializingIf(Option<SkipSerializingIfFn>)
Conditionally skips serialization based on a predicate function.
Stores a type-erased function pointer: fn(PtrConst) -> bool.
Usage: #[facet(skip_serializing_if = is_empty)]
SkipUnlessTruthy
Skips serialization unless the value is truthy. Uses the type’s registered truthiness predicate when available.
Usage: #[facet(skip_unless_truthy)]
SkipDeserializing
Skips deserialization of this field (uses default value).
Usage: #[facet(skip_deserializing)]
Untagged
For enums: variants are serialized without a discriminator tag.
Usage: #[facet(untagged)]
Other
Marks an enum variant as a catch-all for unknown variant names.
When deserializing, if no variant matches the input tag,
the variant marked with other will be used.
Usage: #[facet(other)]
IsNumeric
Serializes/Deserializers enum to/from integer based on variant discriminant.
Usage: #[facet(is_numeric)]
Cow
Marks an enum as having cow-like semantics (Borrowed/Owned variants).
When deserializing into a cow-like enum and borrowing is not available
(e.g., from JSON), the deserializer automatically selects the Owned variant
instead of the Borrowed variant. This allows types like Stem<'a> to be
deserialized from formats that cannot provide borrowed data.
Requirements:
- The enum must have exactly 2 variants named
BorrowedandOwned Borrowedtypically contains a reference type (e.g.,&'a str)Ownedcontains an owned equivalent (e.g.,String,CompactString)
Usage: #[facet(cow)]
§Example
#[derive(Facet)]
#[facet(cow)]
#[repr(u8)]
pub enum Stem<'a> {
Borrowed(&'a str),
Owned(CompactString),
}Pod
Marks a type as Plain Old Data.
POD types have no invariants - any combination of valid field values produces a valid instance. This enables safe mutation through reflection (poke operations).
Usage: #[facet(pod)]
Rename(&'static str)
Renames a field or variant during serialization/deserialization.
Usage: #[facet(rename = "new_name")]
RenameAll(&'static str)
Renames all fields/variants using a case conversion rule.
Usage: #[facet(rename_all = "camelCase")]
Supported rules: camelCase, snake_case, PascalCase, SCREAMING_SNAKE_CASE, kebab-case, SCREAMING-KEBAB-CASE
Alias(&'static str)
Aliases a field or variant during deserialization.
Usage: #[facet(alias = "additional_name")]
Allows for deserializing a field from either the alias or the original name.
Tag(Option<&'static str>)
Tag attribute with dual usage:
Container-level (with value): For internally/adjacently tagged enums, specifies the field name for the discriminator tag.
Usage: #[facet(tag = "type")]
Field-level (without value): Within an #[facet(other)] variant,
marks a field as capturing the variant tag name when deserializing
self-describing formats that emit VariantTag events.
Usage: #[facet(tag)] on a String field
Content(Option<&'static str>)
Content attribute with dual usage:
Container-level (with value): For adjacently tagged enums, specifies the field name for the variant content.
Usage: #[facet(content = "data")]
Field-level (without value): Within an #[facet(other)] variant,
marks a field as capturing the variant payload when deserializing
self-describing formats that emit VariantTag events.
Usage: #[facet(content)] on a field
TypeTag(&'static str)
Identifies the type with a tag for self-describing formats.
Usage: #[facet(type_tag = "com.example.MyType")]
Invariants(Option<InvariantsFn>)
Type invariant validation function.
Stores a type-erased function pointer: fn(PtrConst) -> bool.
Usage: #[facet(invariants = validate_fn)]
Truthy(Option<TruthyFn>)
Declares the truthiness predicate for this container type.
Stores a type-erased function pointer: fn(PtrConst) -> bool.
Usage: #[facet(truthy = Self::is_truthy)]
SkipAllUnlessTruthy
Applies skip_unless_truthy to every field in the container.
Usage: #[facet(skip_all_unless_truthy)]
Proxy(&'static Shape)
Proxy type for serialization and deserialization.
The proxy type must implement TryFrom<ProxyType> for FieldType (for deserialization)
and TryFrom<&FieldType> for ProxyType (for serialization).
Usage: #[facet(proxy = MyProxyType)]
RecursiveType
Marks a field as having a recursive type that needs lazy shape resolution.
Use this on fields where the type recursively contains the parent type,
such as Vec<Self>, Box<Self>, Option<Arc<Self>>, etc.
Without this attribute, such recursive types would cause a compile-time cycle. With this attribute, the field’s shape is resolved lazily via a closure.
Usage: #[facet(recursive_type)]
§Example
#[derive(Facet)]
struct Node {
value: i32,
#[facet(recursive_type)]
children: Vec<Node>,
}Where(&'static str)
Adds custom trait bounds to the generated Facet impl. The bounds are added to the where clause alongside auto-generated bounds.
Usage: #[facet(where T: Clone + Send)]
When you need a type parameter to implement Facet (e.g., for proxy types),
use a higher-ranked trait bound: #[facet(where T: for<'f> Facet<'f>)]
If HRTB is too restrictive, you can use the internal lifetime 'ʄ directly:
#[facet(where T: Facet<'ʄ>)] (note: 'ʄ is internal and may change).
Traits(&'static str)
Adds custom traits to the generated Facet impl.
Usage: #[facet(traits(Trait1, Trait2))]
When you need a type parameter to implement Facet (e.g., for proxy types),
use a higher-ranked trait bound: #[facet(traits(for<'f> Facet<'f>))]
If HRTB is too restrictive, you can use the internal lifetime 'ʄ directly:
#[facet(traits(Facet<'ʄ>))] (note: 'ʄ is internal and may change).
AutoTraits
Automatically identifies which traits are implemented by the type.
Metadata(&'static str)
Adds metadata to the annotated field.
Crate(&'static str)
Specifies facet’s path in case it’s not in the default location.
FromRef
Infallible constructor from a reference type.
The function must have signature fn(&'a R) -> Self where R is the source type.
Usage: #[facet(from_ref = Self::from_ref)]
Note: This is compile-time only. The path is read from raw tokens by the derive macro.
TryFromRef
Fallible constructor from a reference type.
The function must have signature fn(&'a R) -> Result<Self, E> where R is the source type.
Usage: #[facet(try_from_ref = Self::try_from_ref)]
Note: This is compile-time only. The path is read from raw tokens by the derive macro.
Attribute
Marks a field as an XML/HTML attribute on the element tag.
Usage: #[facet(attribute)]
Fields marked as attributes are serialized as XML/HTML element attributes rather than child elements or text content.
Text
Marks a field as text content within an XML/HTML element.
Usage: #[facet(text)]
Fields marked as text contain the text content of the element, as opposed to child elements or attributes.
CustomElement
Marks an enum variant as a catch-all for custom/unknown elements.
Usage: #[facet(custom_element)]
When deserializing XML/HTML, unknown element tags are captured
by the variant marked with custom_element.