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§
Required Methods§
Sourcefn begin_struct(&mut self) -> Result<(), Self::Error>
fn begin_struct(&mut self) -> Result<(), Self::Error>
Begin a map/object/struct.
Sourcefn field_key(&mut self, key: &str) -> Result<(), Self::Error>
fn field_key(&mut self, key: &str) -> Result<(), Self::Error>
Emit a field key within a struct.
Sourcefn end_struct(&mut self) -> Result<(), Self::Error>
fn end_struct(&mut self) -> Result<(), Self::Error>
End a map/object/struct.
Provided Methods§
Sourcefn emit_field_key(&mut self, key: &FieldKey<'_>) -> Result<(), Self::Error>
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.
Sourcefn field_metadata(&mut self, _field: &FieldItem) -> Result<(), Self::Error>
fn field_metadata(&mut self, _field: &FieldItem) -> Result<(), Self::Error>
Optional: Provide field metadata before field_key is called. Default implementation does nothing.
Sourcefn field_metadata_with_value(
&mut self,
_field: &FieldItem,
_value: Peek<'_, '_>,
) -> Result<bool, Self::Error>
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).
Sourcefn struct_metadata(&mut self, _shape: &Shape) -> Result<(), Self::Error>
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.
Sourcefn variant_metadata(
&mut self,
_variant: &'static Variant,
) -> Result<(), Self::Error>
fn variant_metadata( &mut self, _variant: &'static Variant, ) -> Result<(), Self::Error>
Optional: Provide variant metadata before serializing an enum variant. Default implementation does nothing.
Sourcefn serialize_metadata_container(
&mut self,
_container: &PeekStruct<'_, '_>,
) -> Result<bool, Self::Error>
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 8080The format is responsible for:
- Extracting metadata fields (use
field.metadata_kind()to identify them) - Emitting metadata in the appropriate position
- 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).
Sourcefn preferred_field_order(&self) -> FieldOrdering
fn preferred_field_order(&self) -> FieldOrdering
Preferred field ordering for this format. Default is declaration order.
Sourcefn struct_field_mode(&self) -> StructFieldMode
fn struct_field_mode(&self) -> StructFieldMode
Preferred struct field mode for this format.
Sourcefn map_encoding(&self) -> MapEncoding
fn map_encoding(&self) -> MapEncoding
Preferred map encoding for this format.
Sourcefn enum_variant_encoding(&self) -> EnumVariantEncoding
fn enum_variant_encoding(&self) -> EnumVariantEncoding
Preferred enum variant encoding for this format.
Sourcefn is_self_describing(&self) -> bool
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.
Sourcefn dynamic_value_encoding(&self) -> DynamicValueEncoding
fn dynamic_value_encoding(&self) -> DynamicValueEncoding
Preferred dynamic value encoding for this format.
Sourcefn raw_serialize_shape(&self) -> Option<&'static Shape>
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.
Sourcefn raw_scalar(&mut self, content: &str) -> Result<(), Self::Error>
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.
Sourcefn serialize_opaque_scalar(
&mut self,
_shape: &'static Shape,
_value: Peek<'_, '_>,
) -> Result<bool, Self::Error>
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.
Sourcefn dynamic_value_tag(
&mut self,
_tag: DynamicValueTag,
) -> Result<(), Self::Error>
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.
Sourcefn begin_seq_with_len(&mut self, _len: usize) -> Result<(), Self::Error>
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().
Sourcefn begin_map_with_len(&mut self, _len: usize) -> Result<(), Self::Error>
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.
Sourcefn end_map(&mut self) -> Result<(), Self::Error>
fn end_map(&mut self) -> Result<(), Self::Error>
End a map/object/struct.
Default: delegates to end_struct().
Sourcefn serialize_map_key(&mut self, _key: Peek<'_, '_>) -> Result<bool, Self::Error>
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.
Sourcefn typed_scalar(
&mut self,
scalar_type: ScalarType,
value: Peek<'_, '_>,
) -> Result<(), Self::Error>
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().
Sourcefn begin_option_some(&mut self) -> Result<(), Self::Error>
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).
Sourcefn serialize_none(&mut self) -> Result<(), Self::Error>
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.
Sourcefn begin_enum_variant(
&mut self,
_variant_index: usize,
_variant_name: &'static str,
) -> Result<(), Self::Error>
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).
Sourcefn write_variant_tag(
&mut self,
_variant_name: &str,
) -> Result<bool, Self::Error>
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
Sourcefn begin_struct_after_tag(&mut self) -> Result<(), Self::Error>
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().
Sourcefn begin_seq_after_tag(&mut self) -> Result<(), Self::Error>
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().
Sourcefn serialize_byte_sequence(
&mut self,
_bytes: &[u8],
) -> Result<bool, Self::Error>
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.
Sourcefn serialize_byte_array(&mut self, _bytes: &[u8]) -> Result<bool, Self::Error>
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.
Sourcefn format_namespace(&self) -> Option<&'static str>
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).