39 个版本 (9 个重大更改)

0.12.2 2024年8月23日
0.11.1 2024年8月1日
0.11.0 2024年6月13日
0.10.0 2024年2月24日
0.0.6 2022年3月19日

324编码 中排名

Download history 3084/week @ 2024-05-03 4181/week @ 2024-05-10 3477/week @ 2024-05-17 2657/week @ 2024-05-24 2392/week @ 2024-05-31 2433/week @ 2024-06-07 2429/week @ 2024-06-14 3468/week @ 2024-06-21 1910/week @ 2024-06-28 2137/week @ 2024-07-05 1212/week @ 2024-07-12 1275/week @ 2024-07-19 3189/week @ 2024-07-26 3396/week @ 2024-08-02 2934/week @ 2024-08-09 2412/week @ 2024-08-16

每月下载量12,174
用于 8 个crate(5 个直接使用)

MIT/Apache

440KB
11K SLoC

serde_amqp

AMQP1.0 协议和原始类型的 serde 实现。

序列化和反序列化数据结构

任何实现了 serde::Serializeserde::Deserialize 特性的类型都可以使用以下便利函数进行序列化和反序列化

序列化

反序列化

原始类型

AMQP1.0 协议中定义的所有原始类型都可以在 [primitives] 模块中找到。

描述类型

AMQP1.0 规范允许使用 descriptor::Descriptor 注释任何 AMQP 类型,从而创建一个描述类型。虽然可以使用 described::DescribedValue 构建,但定义自定义描述类型的更简单方法是使用自定义 SerializeCompositeDeserializeComposite derive 宏。请注意,必须启用 "derive" 功能标志。

您可以在相应的 部分 中了解更多有关如何使用 derive 宏的信息。

未类型化的 AMQP1.0 值

可以使用 Value 构建、序列化和反序列化未类型化的 AMQP1.0 值。

use serde_amqp::{
    SerializeComposite, DeserializeComposite, Value, to_vec, from_slice,
    described::Described, descriptor::Descriptor,
};

#[derive(Debug, SerializeComposite, DeserializeComposite)]
#[amqp_contract(code = "0x00:0x13", encoding = "list")]
struct Foo(Option<bool>, Option<i32>);

let foo = Foo(Some(true), Some(3));
let buf = to_vec(&foo).unwrap();
let value: Value = from_slice(&buf).unwrap();
let expected = Value::from(
    Described {
        descriptor: Descriptor::Code(0x13),
        value: Value::List(vec![
            Value::Bool(true),
            Value::Int(3)
        ])
    }
);
assert_eq!(value, expected);

实现了 serde::Serializeserde::Deserialize 特性的类型也可以使用 Value 进行转换,使用 to_valuefrom_value 函数。

警告 enum

enum 在 serde 数据模型中可以分为以下几类。

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
enum Enumeration {
    UnitVariant,
    NewTypeVariant(u32),
    TupleVariant(bool, u64, String),
    StructVariant { id: u32, is_true: bool },
}

AMQP1.0 协议本身不支持 NewTypeVariantTupleVariantStructVariant。为了完整性,这些变体的序列化和反序列化实现如下:

  • NewTypeVariant 被编码/解码为一个包含单个键值对的映射,变体索引作为键,单个包装字段作为值。
  • TupleVariant 被编码/解码为一个包含单个键值对的映射,变体索引作为键,字段列表作为值。
  • StructVariant 被编码/解码为一个包含单个键值对的映射,变体索引作为键,字段列表作为值。

功能标志

default = []
功能 描述
"derive" 启用 SerializeCompositeDeserializeComposite
"extensions" 启用 extensions 模块(见 Extensions),自 "0.4.5" 版本开始添加
"time" 启用 Timestamp 从/到 time::Durationtime::OffsetDateTime 的转换,自 "0.5.1" 版本开始添加
"chrono" 启用 Timestamp 从/到 chrono::Durationchrono::DateTime 的转换,自 "0.5.1" 版本开始添加
"chrono-preview" 一个临时功能,用于移除在 chrono 包中使用的已弃用 API
"uuid" 启用 Uuid 从/到 uuid::Uuid 的转换,自 "0.5.1" 版本开始添加

SerializeCompositeDeserializeComposite

宏提供三种编码类型

  1. "list":结构体将序列化为一个描述列表。描述列表是一个带有其描述符前置的 AMQP1.0 列表。反序列化将接受 "list""map" 编码的值。
  2. "map":结构体将序列化为一个描述映射。描述映射是一个带有其描述符前置的 AMQP1.0 映射。反序列化将接受 "list""map" 编码的值。
  3. "basic":结构体必须是一个瘦包装器(仅包含一个字段),包装另一个可序列化/反序列化的类型。内部结构将使用附加到结构体的描述符进行序列化/反序列化。

有关"list"编码的详细信息

可选字段

如果字段在规范中没有标记为"mandatory",则该字段可以是Option。在序列化过程中,可选字段可能完全跳过或编码为AMQP1.0 null原语(0x40)。在反序列化过程中,AMQP1.0 null原语或空字段将被解码为None

具有默认值的字段

对于规范中定义了默认值的字段,字段类型必须实现DefaultPartialEq特性。在序列化过程中,如果字段等于字段类型的默认值,则该字段将被完全忽略或编码为AMQP1.0 null原语(0x40)。在反序列化过程中,AMQP1.0 null原语或空字段将被解码为类型的默认值。

derive宏的示例

"list"编码将把Attach结构体编码为描述列表(一个描述符后跟字段列表)。

/// 2.7.3 Attach
/// Attach a link to a session.
/// <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<Array<Symbol>>,

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

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

```rust,ignore
/// 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 OrderedMap<String, SimpleValue>);

扩展

原始u64可以用作宏属性中的描述符代码。这对于定义不严格符合的类型很有用。

use serde_amqp::macros::{SerializeComposite, DeserializeComposite};

#[derive(Debug, Clone, SerializeComposite, DeserializeComposite)]
#[amqp_contract(
    name = "amqp:application-properties:map",
    code = "0x000_0000_0000_0007"   ,
    encoding = "list",
    rename_all = "kebab-case"
)]
pub struct Foo {
   pub bar: String,
}

以下类型在extensions模块中提供,并需要extensions特性

  1. TransparentVec - 一个围绕Vec的瘦包装器,它被序列化/反序列化为一个元素序列Vec被视为核心规范中的AMQP List

许可证:MIT/Apache-2.0

依赖关系

~1.7–3.5MB
~63K SLoC