Skip to main content

FormatSerializer

Trait FormatSerializer 

Source
pub trait FormatSerializer {
    type Error: Debug;

Show 36 methods // Required methods fn begin_struct(&mut self) -> Result<(), Self::Error>; fn field_key(&mut self, key: &str) -> Result<(), Self::Error>; fn end_struct(&mut self) -> Result<(), Self::Error>; fn begin_seq(&mut self) -> Result<(), Self::Error>; fn end_seq(&mut self) -> Result<(), Self::Error>; fn scalar(&mut self, scalar: ScalarValue<'_>) -> Result<(), Self::Error>; // Provided methods fn emit_field_key(&mut self, key: &FieldKey<'_>) -> Result<(), Self::Error> { ... } fn field_metadata(&mut self, _field: &FieldItem) -> Result<(), Self::Error> { ... } fn field_metadata_with_value( &mut self, _field: &FieldItem, _value: Peek<'_, '_>, ) -> Result<bool, Self::Error> { ... } fn struct_metadata(&mut self, _shape: &Shape) -> Result<(), Self::Error> { ... } fn variant_metadata( &mut self, _variant: &'static Variant, ) -> Result<(), Self::Error> { ... } fn serialize_metadata_container( &mut self, _container: &PeekStruct<'_, '_>, ) -> Result<bool, Self::Error> { ... } fn preferred_field_order(&self) -> FieldOrdering { ... } fn struct_field_mode(&self) -> StructFieldMode { ... } fn map_encoding(&self) -> MapEncoding { ... } fn enum_variant_encoding(&self) -> EnumVariantEncoding { ... } fn is_self_describing(&self) -> bool { ... } fn dynamic_value_encoding(&self) -> DynamicValueEncoding { ... } fn raw_serialize_shape(&self) -> Option<&'static Shape> { ... } fn raw_scalar(&mut self, content: &str) -> Result<(), Self::Error> { ... } fn serialize_opaque_scalar( &mut self, _shape: &'static Shape, _value: Peek<'_, '_>, ) -> Result<bool, Self::Error> { ... } fn dynamic_value_tag( &mut self, _tag: DynamicValueTag, ) -> Result<(), Self::Error> { ... } fn begin_seq_with_len(&mut self, _len: usize) -> Result<(), Self::Error> { ... } fn begin_map_with_len(&mut self, _len: usize) -> Result<(), Self::Error> { ... } fn end_map(&mut self) -> Result<(), Self::Error> { ... } fn serialize_map_key( &mut self, _key: Peek<'_, '_>, ) -> Result<bool, Self::Error> { ... } fn typed_scalar( &mut self, scalar_type: ScalarType, value: Peek<'_, '_>, ) -> Result<(), Self::Error> { ... } fn begin_option_some(&mut self) -> Result<(), Self::Error> { ... } fn serialize_none(&mut self) -> Result<(), Self::Error> { ... } fn begin_enum_variant( &mut self, _variant_index: usize, _variant_name: &'static str, ) -> Result<(), Self::Error> { ... } fn write_variant_tag( &mut self, _variant_name: &str, ) -> Result<bool, Self::Error> { ... } fn begin_struct_after_tag(&mut self) -> Result<(), Self::Error> { ... } fn begin_seq_after_tag(&mut self) -> Result<(), Self::Error> { ... } fn serialize_byte_sequence( &mut self, _bytes: &[u8], ) -> Result<bool, Self::Error> { ... } fn serialize_byte_array( &mut self, _bytes: &[u8], ) -> Result<bool, Self::Error> { ... } fn format_namespace(&self) -> Option<&'static str> { ... }
}
Expand description

Low-level serializer interface implemented by each format backend.

This is intentionally event-ish: the shared serializer logic owns traversal (struct/enum/seq decisions), while formats own representation details.

Required Associated Types§

Source

type Error: Debug

Format-specific error type.

Required Methods§

Source

fn begin_struct(&mut self) -> Result<(), Self::Error>

Begin a map/object/struct.

Source

fn field_key(&mut self, key: &str) -> Result<(), Self::Error>

Emit a field key within a struct.

Source

fn end_struct(&mut self) -> Result<(), Self::Error>

End a map/object/struct.

Source

fn begin_seq(&mut self) -> Result<(), Self::Error>

Begin a sequence/array.

Source

fn end_seq(&mut self) -> Result<(), Self::Error>

End a sequence/array.

Source

fn scalar(&mut self, scalar: ScalarValue<'_>) -> Result<(), Self::Error>

Emit a scalar value.

Provided Methods§

Source

fn emit_field_key(&mut self, key: &FieldKey<'_>) -> Result<(), Self::Error>

Emit a rich field key with optional tag and documentation.

This is called when serializing map keys that have been extracted from metadata containers (like ObjectKey with tag support).

Default implementation ignores tag and doc, just emits the name. Formats that support tags (like Styx) should override this.

Source

fn field_metadata(&mut self, _field: &FieldItem) -> Result<(), Self::Error>

Optional: Provide field metadata before field_key is called. Default implementation does nothing.

Source

fn field_metadata_with_value( &mut self, _field: &FieldItem, _value: Peek<'_, '_>, ) -> Result<bool, Self::Error>

Optional: Provide field metadata with access to the field value.

This is called before field_key and allows formats to inspect the field value for metadata. This is particularly useful for metadata containers like Documented<T> where doc comments are stored in the value, not the field definition.

If this returns Ok(true), the field key has been written and field_key will be skipped. If this returns Ok(false), normal field_key handling continues.

Default implementation does nothing and returns Ok(false).

Source

fn struct_metadata(&mut self, _shape: &Shape) -> Result<(), Self::Error>

Optional: Provide struct/enum type metadata when beginning to serialize it. Default implementation does nothing.

Source

fn variant_metadata( &mut self, _variant: &'static Variant, ) -> Result<(), Self::Error>

Optional: Provide variant metadata before serializing an enum variant. Default implementation does nothing.

Source

fn serialize_metadata_container( &mut self, _container: &PeekStruct<'_, '_>, ) -> Result<bool, Self::Error>

Serialize a metadata container value.

Metadata containers (structs with #[facet(metadata_container)]) have exactly one non-metadata field (the actual value) and one or more metadata fields (like doc comments or source spans).

Formats that support metadata can override this to emit metadata in the appropriate position. For example, Styx emits doc comments before the value:

/// The port to listen on
port 8080

The format is responsible for:

  1. Extracting metadata fields (use field.metadata_kind() to identify them)
  2. Emitting metadata in the appropriate position
  3. Serializing the non-metadata field value

Returns Ok(true) if handled, Ok(false) to fall back to default transparent serialization (which just serializes the non-metadata field).

Source

fn preferred_field_order(&self) -> FieldOrdering

Preferred field ordering for this format. Default is declaration order.

Source

fn struct_field_mode(&self) -> StructFieldMode

Preferred struct field mode for this format.

Source

fn map_encoding(&self) -> MapEncoding

Preferred map encoding for this format.

Source

fn enum_variant_encoding(&self) -> EnumVariantEncoding

Preferred enum variant encoding for this format.

Source

fn is_self_describing(&self) -> bool

Whether this format is self-describing (includes type information).

Self-describing formats (JSON, YAML, TOML) can deserialize without hints and treat newtypes transparently. Non-self-describing formats (ASN.1, postcard, msgpack) require structural hints and wrap newtypes.

Default is true for text-based formats.

Source

fn dynamic_value_encoding(&self) -> DynamicValueEncoding

Preferred dynamic value encoding for this format.

Source

fn raw_serialize_shape(&self) -> Option<&'static Shape>

Returns the shape of the format’s raw capture type for serialization.

When serializing a value whose shape matches this, the serializer will extract the inner string and call FormatSerializer::raw_scalar instead of normal serialization.

Source

fn raw_scalar(&mut self, content: &str) -> Result<(), Self::Error>

Emit a raw scalar value (for RawJson, etc.) without any encoding/escaping.

The content is the format-specific raw representation that should be output directly.

Source

fn serialize_opaque_scalar( &mut self, _shape: &'static Shape, _value: Peek<'_, '_>, ) -> Result<bool, Self::Error>

Serialize an opaque scalar type with a format-specific encoding.

Returns Ok(true) if handled, Ok(false) to fall back to standard logic.

Source

fn dynamic_value_tag( &mut self, _tag: DynamicValueTag, ) -> Result<(), Self::Error>

Emit a dynamic value type tag.

Formats that use DynamicValueEncoding::Tagged should override this. Self-describing formats can ignore it.

Source

fn begin_seq_with_len(&mut self, _len: usize) -> Result<(), Self::Error>

Begin a sequence with known length.

Binary formats (postcard, msgpack) can use this to write a length prefix before the elements. Text formats can ignore the length and just call begin_seq().

Default: delegates to begin_seq().

Source

fn begin_map_with_len(&mut self, _len: usize) -> Result<(), Self::Error>

Begin serializing a map with known length.

Default: delegates to begin_struct() for formats that encode maps as objects.

Source

fn end_map(&mut self) -> Result<(), Self::Error>

End a map/object/struct.

Default: delegates to end_struct().

Source

fn serialize_map_key(&mut self, _key: Peek<'_, '_>) -> Result<bool, Self::Error>

Serialize a map key in MapEncoding::Struct mode.

This is called for each map key when using struct encoding. The default implementation converts the key to a string (via as_str() or Display) and calls field_key().

Formats can override this to handle special key types differently. For example, Styx overrides this to serialize Option::None as @.

Returns Ok(true) if handled, Ok(false) to use the default behavior.

Source

fn typed_scalar( &mut self, scalar_type: ScalarType, value: Peek<'_, '_>, ) -> Result<(), Self::Error>

Serialize a scalar with full type information.

Binary formats need to encode different integer sizes differently:

  • postcard: u8 as raw byte, u16+ as varint, signed use zigzag
  • msgpack: different tags for different sizes

Text formats can ignore the type and use the normalized ScalarValue.

Default: normalizes to ScalarValue and calls scalar().

Source

fn begin_option_some(&mut self) -> Result<(), Self::Error>

Begin serializing Option::Some(value).

Binary formats like postcard write a 0x01 discriminant byte here. Text formats typically don’t need a prefix (they just serialize the value).

Default: no-op (text formats).

Source

fn serialize_none(&mut self) -> Result<(), Self::Error>

Serialize Option::None.

Binary formats like postcard write a 0x00 discriminant byte. Text formats typically emit null.

Default: emits ScalarValue::Null.

Source

fn begin_enum_variant( &mut self, _variant_index: usize, _variant_name: &'static str, ) -> Result<(), Self::Error>

Begin an enum variant with its index and name.

Binary formats like postcard write the variant index as a varint. Text formats typically use the variant name as a key or value.

This is called for externally tagged enums before the variant payload. For untagged enums, this is not called.

Default: no-op (text formats handle variants via field_key/scalar).

Source

fn write_variant_tag( &mut self, _variant_name: &str, ) -> Result<bool, Self::Error>

Write a tag for an externally-tagged enum variant.

Formats like Styx that use @tag syntax for enum variants should override this to write their tag and return Ok(true). The shared serializer will then call the appropriate payload serialization method.

If this returns Ok(false) (the default), the shared serializer uses the standard externally-tagged representation: { "variant_name": payload }.

When returning Ok(true):

  • For unit variants, nothing more is written
  • For newtype variants, the payload is serialized directly after
  • For struct variants, begin_struct_after_tag is called for the payload
Source

fn begin_struct_after_tag(&mut self) -> Result<(), Self::Error>

Begin a struct directly after a variant tag (no separator).

Called after write_variant_tag returns Ok(true) for struct variants. Formats should write { without any preceding space/separator.

Default: calls begin_struct().

Source

fn begin_seq_after_tag(&mut self) -> Result<(), Self::Error>

Begin a sequence directly after a variant tag (no separator).

Called after write_variant_tag returns Ok(true) for tuple variants. Formats should write ( or [ without any preceding space/separator.

Default: calls begin_seq().

Source

fn serialize_byte_sequence( &mut self, _bytes: &[u8], ) -> Result<bool, Self::Error>

Serialize a byte sequence (Vec<u8>, &[u8], etc.) in bulk.

For binary formats like postcard that store byte sequences as raw bytes (varint length followed by raw data), this allows bulk writing instead of element-by-element serialization.

If the serializer handles this, it should write the bytes directly and return Ok(true). If it doesn’t support this optimization, it should return Ok(false) and the serializer will fall back to element-by-element serialization.

Returns Ok(true) if handled (bytes were written), Ok(false) otherwise.

Source

fn serialize_byte_array(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error>

Serialize a fixed-size byte array ([u8; N]) in bulk.

Unlike serialize_byte_sequence, this does NOT write a length prefix since the array size is known from the type.

Returns Ok(true) if handled (bytes were written), Ok(false) otherwise.

Source

fn format_namespace(&self) -> Option<&'static str>

Returns the format namespace for format-specific proxy resolution.

When a field or container has format-specific proxies (e.g., #[facet(xml::proxy = XmlProxy)]), this namespace is used to look up the appropriate proxy. If no namespace is returned, only the format-agnostic proxy (#[facet(proxy = ...)]) is considered.

Examples:

  • XML serializer should return Some("xml")
  • JSON serializer should return Some("json")

Default: returns None (only format-agnostic proxies are used).

Implementors§