aldrin-macros 0.13.0

Aldrin macros.
Documentation

Aldrin macros

The macros in this crate are not generally meant to be used directly, but through re-exports in other crates.

Procedural macros

  • generate: Re-exported in crate aldrin
  • service: Re-exported in crate aldrin

Derive macros

  • [Tag]
  • [PrimaryTag]
  • [RefType]
  • [Serialize]
  • [Deserialize]
  • [Introspectable]
  • [KeyTag]
  • [PrimaryKeyTag]
  • [SerializeKey]

All derive macros are re-exported in both aldrin and aldrin-core.

Attributes

All derive macros support various attributes and some apply to multiple macros.

Container attributes

crate

The attribute #[aldrin(crate = ...) can be used to override the path of the aldrin_core crate. This is useful when aldrin_core is not a direct dependency, but only reexported somewhere. The default value depends on from where the macro is invoked, it's either ::aldrin::core or ::aldrin_core.

mod my_reexports {
    pub use aldrin_core as my_aldrin_core;
}

#[derive(
    my_reexports::my_aldrin_core::Tag,
    my_reexports::my_aldrin_core::PrimaryTag,
    my_reexports::my_aldrin_core::RefType,
    my_reexports::my_aldrin_core::Serialize,
    my_reexports::my_aldrin_core::Deserialize,
)]
#[aldrin(crate = my_reexports::my_aldrin_core, ref_type)]
struct Person {
    name: String,
}
schema
  • Applies to: [Introspectable]

Deriving Introspectable requires specifying a schema name. It is an error if this attribute is missing.

# use aldrin_core::Introspectable;
#[derive(Introspectable)]
#[aldrin(schema = "contacts")]
struct Person {
    name: String,
}
ref_type
  • Applies to: [RefType], [Serialize] and [SerializeKey]

Deriving RefType requires specifying an identifier for the type with the #[aldrin(ref_type = ...)] attribute. The Serialize and SerializeKey derive macro will then also generate implementations for that type.

It is also possible to specifiy just #[aldrin(ref_type)] without an identifer. In this case, a default will be chosen by appending Ref to the name of the annotated type.

newtype
  • Applies to: [Serialize], [Deserialize], [KeyTag], [PrimaryKeyTag], [SerializeKey], and [DeserializeKey].

Specifying #[aldrin(newtype)] is possible for structs with exactly 1 field and makes them behave like that field. E.g., the type will no longer serialize as a struct, but directly as that field instead.

# use aldrin_core::{
#     Deserialize, DeserializeKey, KeyTag, PrimaryKeyTag, PrimaryTag, Serialize, SerializeKey,
#     Tag,
# };
#[derive(
    Tag,
    KeyTag,
    PrimaryTag,
    PrimaryKeyTag,
    Serialize,
    SerializeKey,
    Deserialize,
    DeserializeKey,
)]
#[aldrin(newtype)]
struct Name {
    inner: String,
}
doc
  • Applies to: [Introspectable]

Provides an alternative doc string used only for deriving [Introspectable]. Note that this attribute can be used anywhere a regular doc comment can be used as well.

If this is not provided then [Introspectable] will fall back to the regular doc comment (if present).

Using this attribute can be desirable if the regular doc comment is Rust-specific, e.g. due to link conversion or other modifications.

# use aldrin_core::{Introspectable};
/// This doc comment will be rendered by rustdoc.
#[derive(Introspectable)]
#[aldrin(schema = "family_tree")]
#[aldrin(doc = "This doc comment will be used for introspection.")]
struct Name {
    /// This doc comment will be rendered by rustdoc.
    #[aldrin(doc = "This doc comment will be used for introspection.")]
    inner: String,
}

Field and variant attributes

id
  • Applies to: [Serialize], [Deserialize] and [Introspectable]

Use #[aldrin(id = ...)] to override the automatically defined id for a field or variant.

Default ids start at 0 for the first field or variant and then increment by 1 for each subsequent field or variant.

# use aldrin_core::{Deserialize, Introspectable, PrimaryTag, RefType, Serialize, Tag};
#[derive(Tag, PrimaryTag, RefType, Serialize, Deserialize, Introspectable)]
#[aldrin(schema = "family_tree", ref_type)]
struct Person {
    age: u8, // id = 0

    #[aldrin(id = 5)]
    name: String, // id = 5

    siblings: Vec<Self>, // id = 6
}
# use aldrin_core::{Deserialize, Introspectable, PrimaryTag, RefType, Serialize, Tag};
#[derive(Tag, PrimaryTag, RefType, Serialize, Deserialize, Introspectable)]
#[aldrin(schema = "pets", ref_type)]
enum Pet {
    Dog, // id = 0

    #[aldrin(id = 5)]
    Cat, // id = 5

    Alpaca, // id = 6
}
optional
  • Applies to: [Serialize], [Deserialize] and [Introspectable]

Use #[aldrin(optional)] to mark fields of a struct as optional. They must be of an Option<T> type.

Optional fields are not serialized if None and are allowed to be missing when deserializing a value.

# use aldrin_core::{Deserialize, Introspectable, PrimaryTag, RefType, Serialize, Tag};
#[derive(Tag, PrimaryTag, RefType, Serialize, Deserialize, Introspectable)]
#[aldrin(schema = "example", ref_type)]
struct MyStruct {
    required_field_1: i32,
    required_field_2: Option<i32>,

    #[aldrin(optional)]
    optional_field: Option<i32>,
}

Both fields required_field_1 and required_field_2 will always be serialized and deserialization will fail if either is missing. Serialization of optional_field is skipped if it is None. If it's missing during deserialization, then it will be set to None.

fallback
  • Applies to: [Serialize], [Deserialize] and [Introspectable]

The last field of a struct and the last variant of an enum can optionally be marked with #[aldrin(fallback)]. This will enable successful serialization and deserialization of unknown fields and variants. For structs, the field type must be aldrin_core::UnknownFields. For enums, the variant must have a single field of type aldrin_core::UnknownVariant.

This attribute cannot be combined with #[aldrin(optional)].

Example of a struct with a fallback field:

# use aldrin_core::{Deserialize, Introspectable, PrimaryTag, RefType, Serialize, Tag, UnknownFields};
#[derive(Tag, PrimaryTag, RefType, Serialize, Deserialize, Introspectable)]
#[aldrin(schema = "contacts", ref_type)]
struct Person {
    name: String,
    age: u8,

    #[aldrin(fallback)]
    unknown_fields: UnknownFields,
}

Example of an enum with a fallback variant:

# use aldrin_core::{Deserialize, Introspectable, PrimaryTag, RefType, Serialize, Tag, UnknownVariant};
#[derive(Tag, PrimaryTag, RefType, Serialize, Deserialize, Introspectable)]
#[aldrin(schema = "zoo", ref_type)]
enum AnimalType {
    Alpaca,
    Pig,

    #[aldrin(fallback)]
    Unkown(UnknownVariant),
}
doc
  • Applies to: [Introspectable]

See doc for containers.