#amqp #serde #descriptor #macro #described #field #deserialize

macro serde_amqp_derive

Custom derive macros for serde_amqp

8 releases

0.2.1 Nov 20, 2022
0.2.0 Oct 12, 2022
0.1.2 Aug 28, 2022
0.1.1 Jul 22, 2022
0.0.1 Feb 21, 2022

#20 in #described

Download history 1350/week @ 2023-12-05 1142/week @ 2023-12-12 925/week @ 2023-12-19 338/week @ 2023-12-26 1038/week @ 2024-01-02 2463/week @ 2024-01-09 1713/week @ 2024-01-16 1262/week @ 2024-01-23 3925/week @ 2024-01-30 3776/week @ 2024-02-06 4599/week @ 2024-02-13 4399/week @ 2024-02-20 4582/week @ 2024-02-27 4818/week @ 2024-03-05 4068/week @ 2024-03-12 2560/week @ 2024-03-19

16,610 downloads per month
Used in 8 crates (via serde_amqp)

MIT/Apache

55KB
1K SLoC

serde_amqp_derive

Provides custom derive macros SerializeComposite and DeserializeComposite for described types as defined in the AMQP1.0 protocol.

Usage

The macro provides three types of encodings:

  1. "list": The struct will be serialized as a described list. A described list is an AMQP1.0 list with its descriptor prepended to the list itself. The deserialization will take either the "list" or the "map" encoded values.
  2. "map": The struct will be serialized as a described map. A described map is an AMQP1.0 map with its descriptor prepended to the map. The deserialization will take either the "list" or the "map" encoded values.
  3. "basic": The struct must be a thin wrapper (containing only one field) over another serializable/deserializable type. The inner struct will be serialized/deserialized with the descriptor prepended to the struct.

Details with the "list" encoding

Optinal fields

If a field is not marked with "mandatory" in the specification, the field can be an Option. During serialization, the optional fields may be skipped completely or encoded as an AMQP1.0 null primitive (0x40). During deserialization, an AMQP1.0 null primitive or an empty field will be decoded as a None.

Fields with default values:

For fields that have default values defined in the specification, the field type must implement both the Default and PartialEq trait. During serialization, if the field is equal to the default value of the field type, the field will be either ignored completely or encoded as an AMQP1.0 null primitive (0x40). During deserialization, an AMQP1.0 null primitive or an empty field will be decoded as the default value of the type.

Example

The "list" encoding will encode the Attach struct as a described list (a descriptor followed by a list of the fields).

/// <type name="attach" class="composite" source="list" provides="frame">
///     <descriptor name="amqp:attach:list" code="0x00000000:0x00000012"/>
#[derive(Debug, DeserializeComposite, SerializeComposite)]
#[amqp_contract(
    name = "amqp:attach:list",
    code = "0x0000_0000:0x0000_0012",
    encoding = "list",
    rename_all = "kebab-case"
)]
pub struct Attach {
    /// <field name="name" type="string" mandatory="true"/>
    pub name: String,

    /// <field name="handle" type="handle" mandatory="true"/>
    pub handle: Handle,

    /// <field name="role" type="role" mandatory="true"/>
    pub role: Role,

    /// <field name="snd-settle-mode" type="sender-settle-mode" default="mixed"/>
    #[amqp_contract(default)]
    pub snd_settle_mode: SenderSettleMode,

    /// <field name="rcv-settle-mode" type="receiver-settle-mode" default="first"/>
    #[amqp_contract(default)]
    pub rcv_settle_mode: ReceiverSettleMode,

    /// <field name="source" type="*" requires="source"/>
    pub source: Option<Source>,

    /// <field name="target" type="*" requires="target"/>
    pub target: Option<Target>,

    /// <field name="unsettled" type="map"/>
    pub unsettled: Option<BTreeMap<DeliveryTag, DeliveryState>>,

    /// <field name="incomplete-unsettled" type="boolean" default="false"/>
    #[amqp_contract(default)]
    pub incomplete_unsettled: Boolean,

    /// <field name="initial-delivery-count" type="sequence-no"/>
    pub initial_delivery_count: Option<SequenceNo>,

    /// <field name="max-message-size" type="ulong"/>
    pub max_message_size: Option<ULong>,

    /// <field name="offered-capabilities" type="symbol" multiple="true"/>
    pub offered_capabilities: Option<Vec<Symbol>>,

    /// <field name="desired-capabilities" type="symbol" multiple="true"/>
    pub desired_capabilities: Option<Vec<Symbol>>,

    /// <field name="properties" type="fields"/>
    pub properties: Option<Fields>,
}

The basic encoding will have ApplicationProperties encoded as a descriptor followed by the wrapped element, which is a map.

/// 3.2.5 Application Properties
/// <type name="application-properties" class="restricted" source="map" provides="section">
///     <descriptor name="amqp:application-properties:map" code="0x00000000:0x00000074"/>
/// </type>
#[derive(Debug, Clone, SerializeComposite, DeserializeComposite)]
#[amqp_contract(
    name = "amqp:application-properties:map",
    code = "0x0000_0000:0x0000_0074",
    encoding = "basic"
)]
pub struct ApplicationProperties(pub BTreeMap<String, SimpleValue>);

Dependencies

~2.5MB
~49K SLoC