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 |
|
324 在 编码 中排名
每月下载量12,174
用于 8 个crate(5 个直接使用)
440KB
11K SLoC
serde_amqp
AMQP1.0 协议和原始类型的 serde 实现。
序列化和反序列化数据结构
任何实现了 serde::Serialize
和 serde::Deserialize
特性的类型都可以使用以下便利函数进行序列化和反序列化
序列化
反序列化
原始类型
AMQP1.0 协议中定义的所有原始类型都可以在 [primitives] 模块中找到。
描述类型
AMQP1.0 规范允许使用 descriptor::Descriptor
注释任何 AMQP 类型,从而创建一个描述类型。虽然可以使用 described::Described
和 Value
构建,但定义自定义描述类型的更简单方法是使用自定义 SerializeComposite
和 DeserializeComposite
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::Serialize
和 serde::Deserialize
特性的类型也可以使用 Value
进行转换,使用 to_value
和 from_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 协议本身不支持 NewTypeVariant
、TupleVariant
或 StructVariant
。为了完整性,这些变体的序列化和反序列化实现如下:
NewTypeVariant
被编码/解码为一个包含单个键值对的映射,变体索引作为键,单个包装字段作为值。TupleVariant
被编码/解码为一个包含单个键值对的映射,变体索引作为键,字段列表作为值。StructVariant
被编码/解码为一个包含单个键值对的映射,变体索引作为键,字段列表作为值。
功能标志
default = []
功能 | 描述 |
---|---|
"derive" |
启用 SerializeComposite 和 DeserializeComposite |
"extensions" |
启用 extensions 模块(见 Extensions),自 "0.4.5" 版本开始添加 |
"time" |
启用 Timestamp 从/到 time::Duration 和 time::OffsetDateTime 的转换,自 "0.5.1" 版本开始添加 |
"chrono" |
启用 Timestamp 从/到 chrono::Duration 和 chrono::DateTime 的转换,自 "0.5.1" 版本开始添加 |
"chrono-preview" |
一个临时功能,用于移除在 chrono 包中使用的已弃用 API |
"uuid" |
启用 Uuid 从/到 uuid::Uuid 的转换,自 "0.5.1" 版本开始添加 |
SerializeComposite
和 DeserializeComposite
宏提供三种编码类型
"list"
:结构体将序列化为一个描述列表。描述列表是一个带有其描述符前置的 AMQP1.0 列表。反序列化将接受"list"
或"map"
编码的值。"map"
:结构体将序列化为一个描述映射。描述映射是一个带有其描述符前置的 AMQP1.0 映射。反序列化将接受"list"
或"map"
编码的值。"basic"
:结构体必须是一个瘦包装器(仅包含一个字段),包装另一个可序列化/反序列化的类型。内部结构将使用附加到结构体的描述符进行序列化/反序列化。
有关"list"
编码的详细信息
可选字段
如果字段在规范中没有标记为"mandatory"
,则该字段可以是Option
。在序列化过程中,可选字段可能完全跳过或编码为AMQP1.0 null
原语(0x40
)。在反序列化过程中,AMQP1.0 null
原语或空字段将被解码为None
。
具有默认值的字段
对于规范中定义了默认值的字段,字段类型必须实现Default
和PartialEq
特性。在序列化过程中,如果字段等于字段类型的默认值,则该字段将被完全忽略或编码为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
特性
TransparentVec
- 一个围绕Vec
的瘦包装器,它被序列化/反序列化为一个元素序列Vec
被视为核心规范中的AMQPList
许可证:MIT/Apache-2.0
依赖关系
~1.7–3.5MB
~63K SLoC