AvroSchema

Trait AvroSchema 

Source
pub trait AvroSchema {
    // Required method
    fn get_schema() -> Schema;
}
Expand description

Trait for types that serve as an Avro data model.

Do not implement directly! Either derive it or implement AvroSchemaComponent to get this trait through a blanket implementation.

§Deriving AvroSchema

Using the custom derive requires that you enable the "derive" cargo feature in your Cargo.toml:

[dependencies]
apache-avro = { version = "..", features = ["derive"] }

Then, you add the #[derive(AvroSchema)] annotation to your struct and enum type definition:

#[derive(AvroSchema, Serialize, Deserialize)]
pub struct Foo {
    bar: Vec<Bar>,
}

#[derive(AvroSchema, Serialize, Deserialize)]
pub enum Bar {
    Spam,
    Maps
}

This will implement AvroSchemaComponent for the type, and AvroSchema through the blanket implementation for T: AvroSchemaComponent.

When deriving structs, every member must also implement AvroSchemaComponent.

§Changing the generated schema

The derive macro will read both the avro and serde attributes to modify the generated schema. It will also check for compatibility between the various attributes.

§Container attributes
  • #[serde(rename = "name")]

    Set the name of the schema to the given string. Defaults to the name of the type.

  • #[avro(namespace = "some.name.space")]

    Set the namespace of the schema. This will be the relative namespace if the schema is included in another schema.

  • #[avro(doc = "Some documentation")]

    Set the doc attribute of the schema. Defaults to the documentation of the type.

  • #[avro(alias = "name")]

    Set the alias attribute of the schema. Can be specified multiple times.

  • #[serde(rename_all = "camelCase")]

    Rename all the fields or variants in the schema to follow the given case convention. The possible values are "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "kebab-case", "SCREAMING_SNAKE_CASE", "SCREAMING-KEBAB-CASE".

  • #[serde(transparent)]

    Use the schema of the inner field directly. Is only allowed on structs with only one unskipped field.

§Variant attributes
  • #[serde(rename = "name")]

    Rename the variant to the given name.

§Field attributes
  • #[serde(rename = "name")]

    Rename the field name to the given name.

  • #[avro(doc = "Some documentation")]

    Set the doc attribute of the field. Defaults to the documentation of the field.

  • #[avro(default = "null")]

    Set the default attribute of the field.

    Note: This is a JSON value not a Rust value, as this is put in the schema itself.

  • #[serde(alias = "name")]

    Set the alias attribute of the field. Can be specified multiple times.

  • #[serde(flatten)]

    Flatten the content of this field into the container it is defined in.

  • #[serde(skip)]

    Do not include this field in the schema.

  • #[serde(skip_serializing)]

    When combined with #[serde(skip_deserializing)], don’t include this field in the schema. Otherwise, it will be included in the schema and the #[avro(default)] attribute must be set. That value will be used for serializing.

  • #[serde(skip_serializing_if)]

    Conditionally use the value of the field or the value provided by #[avro(default)]. The #[avro(default)] attribute must be set.

  • #[avro(with)] and #[serde(with = "module")]

    Override the schema used for this field. See Working with foreign types.

§Incompatible Serde attributes

The derive macro is compatible with most Serde attributes, but it is incompatible with the following attributes:

  • Container attributes
    • tag
    • content
    • untagged
    • variant_identifier
    • field_identifier
    • remote
    • rename_all(serialize = "..", deserialize = "..") where serialize != deserialize
  • Variant attributes
    • other
    • untagged
  • Field attributes
    • getter

§Working with foreign types

Most foreign types won’t have a AvroSchema implementation. This crate implements it only for built-in types and uuid::Uuid.

To still be able to derive schemas for fields of foreign types, the #[avro(with)] attribute can be used to get the schema for those fields. It can be used in two ways:

  1. In combination with #[serde(with = "path::to::module)]

    To get the schema, it will call the functions fn get_schema_in_ctxt(&mut HashSet<Name>, &Namespace) -> Schema and fn get_record_fields_in_ctxt(usize, &mut HashSet<Name>, &Namespace) -> Option<Vec<RecordField>> in the module provided to the Serde attribute. See AvroSchemaComponent for details on how to implement those functions.

  2. By providing a function directly, #[avro(with = some_fn)].

    To get the schema, it will call the function provided. It must have the signature fn(&mut HashSet<Name>, &Namespace) -> Schema. When this is used for a transparent struct, the default implementation of AvroSchemaComponent::get_record_fields_in_ctxt will be used. This is only recommended for primitive types, as the default implementation cannot be efficiently implemented for complex types.

Required Methods§

Source

fn get_schema() -> Schema

Construct the full schema that represents this type.

The returned schema is fully independent and contains only Schema::Ref to named types defined earlier in the schema.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<T> AvroSchema for T