Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serde_amqp Value Serializer not handling nested composite types properly #261

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions fe2o3-amqp-management/src/operations/entity/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,26 @@ pub struct CreateRequest<'a> {
/// to the following rules:
///
/// - A string that consists solely of characters from the ASCII character-set, will be
/// converted into a symbol if so required.
/// converted into a symbol if so required.
///
/// - A string that can be parsed as a number according to [RFC7159] will be converted to a
/// ubyte, ushort, uint, ulong, byte, short, int, or long if so required and the number lies
/// within the domain of the given AMQP type and represents an integral number
/// ubyte, ushort, uint, ulong, byte, short, int, or long if so required and the number lies
/// within the domain of the given AMQP type and represents an integral number
///
/// - A string which can be parsed as a number according to [RFC7159] will be converted to an
/// float, double, decimal32, decimal64 or decimal128 if so required and the number lies within
/// the domain of the given AMQP type.
/// float, double, decimal32, decimal64 or decimal128 if so required and the number lies within
/// the domain of the given AMQP type.
///
/// - A string which can be parsed as true or false according to [RFC7159] will be converted to
/// a boolean value if so required.
/// a boolean value if so required.
///
/// - A string which can be parsed as an array according to [RFC7159] will be converted into a
/// list (with the values type-converted into elements as necessary according to the same rules)
/// if so required.
/// list (with the values type-converted into elements as necessary according to the same rules)
/// if so required.
///
/// - A string which can be parsed as an object according to [RFC7159] will be converted into a
/// map (with the values type-converted into map values as necessary according to the same
/// rules) if so required.
/// map (with the values type-converted into map values as necessary according to the same
/// rules) if so required.
pub body: OrderedMap<String, Value>,
}

Expand Down
2 changes: 2 additions & 0 deletions fe2o3-amqp-management/src/operations/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! A Management Node Operation is an operation directed to the Management Node itself rather than an entity it is managing.
//! Of the standard application-properties (see Section 3.1), name MUST be provided with a value of “self”, type MUST be provided with a value of “org.amqp.management” and identity MUST NOT be provided.
//!
//! The following Management Node Operations SHOULD be supported:
//! - QUERY
//! - GET-TYPES
//! - GET-ANNOTATIONS
//! - GET-ATTRIBUTES
//! - GET-OPERATIONS
//! - GET-MGMT-NODES
//!
//! The following Management Node Operations MAY be supported:
//! - REGISTER
//! - DEREGISTER
Expand Down
1 change: 1 addition & 0 deletions fe2o3-amqp-types/src/performatives/disposition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Disposition {
}

#[cfg(test)]
#[allow(clippy::all)]
mod tests {
use serde_amqp::{from_slice, primitives::Boolean, to_vec};

Expand Down
2 changes: 1 addition & 1 deletion serde_amqp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "serde_amqp"
version = "0.11.0"
version = "0.11.1"
edition = "2021"
description = "A serde implementation of AMQP1.0 protocol."
license = "MIT/Apache-2.0"
Expand Down
4 changes: 4 additions & 0 deletions serde_amqp/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## 0.11.1

1. Fixed a bug with value serializer that doesn't handle nested composite type properly

## 0.11.0

1. Removed deprecated `remove` and `remove_entry` in `OrderedMap`
Expand Down
70 changes: 65 additions & 5 deletions serde_amqp/src/value/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ impl<'a> ser::SerializeSeq for SeqSerializer<'a> {
where
T: serde::Serialize + ?Sized,
{
let val: Value = value.serialize(self.as_mut())?;
let mut se = Serializer::new();
let val: Value = value.serialize(&mut se)?;
self.vec.push(val);
Ok(())
}
Expand All @@ -431,7 +432,8 @@ impl<'a> ser::SerializeTuple for SeqSerializer<'a> {
where
T: serde::Serialize + ?Sized,
{
let val = value.serialize(self.as_mut())?;
let mut se = Serializer::new();
let val = value.serialize(&mut se)?;
self.vec.push(val);
Ok(())
}
Expand Down Expand Up @@ -700,8 +702,9 @@ impl<'a> ser::SerializeMap for MapSerializer<'a> {
K: serde::Serialize + ?Sized,
V: serde::Serialize + ?Sized,
{
let key = key.serialize(self.as_mut())?;
let value = value.serialize(self.as_mut())?;
let mut se = Serializer::new();
let key = key.serialize(&mut se)?;
let value = value.serialize(&mut se)?;
self.map.insert(key, value);
Ok(())
}
Expand Down Expand Up @@ -769,7 +772,8 @@ impl<'a> ser::SerializeTupleVariant for VariantSerializer<'a> {
where
T: serde::Serialize + ?Sized,
{
let value = value.serialize(self.as_mut())?;
let mut se = Serializer::new();
let value = value.serialize(&mut se)?;
self.buf.push(value);
Ok(())
}
Expand Down Expand Up @@ -1033,4 +1037,60 @@ mod tests {
}))
)
}

#[cfg(feature = "derive")]
#[test]
fn test_serialize_nested_composite_some() {
use crate::primitives::Symbol;
#[derive(Debug, Clone, Default, DeserializeComposite, SerializeComposite)]
#[amqp_contract(
name = "amqp:source:list",
code = "0x0000_0000:0x0000_0028",
encoding = "list",
rename_all = "kebab-case"
)]
pub struct Source {
pub address: Option<String>,
pub capabilities: Option<Array<Symbol>>,
}

#[derive(Debug, Clone, Default, DeserializeComposite, SerializeComposite)]
#[amqp_contract(
name = "amqp:target:list",
code = "0x0000_0000:0x0000_0029",
encoding = "list",
rename_all = "kebab-case"
)]
pub struct Target {
pub address: Option<String>,
pub capabilities: Option<Array<Symbol>>,
}

#[derive(Debug, Clone, DeserializeComposite, SerializeComposite)]
#[amqp_contract(
name = "amqp:attach:list",
code = "0x0000_0000:0x0000_0012",
encoding = "list",
rename_all = "kebab-case"
)]
pub struct Attach {
pub source: Option<Source>,
pub target: Option<Target>,
}

let source = Source {
capabilities: Some(Array(Vec::new())),
..Default::default()
};
let target = Target {
address: Some(String::from("some random address")),
capabilities: Some(Array(vec![Symbol::from("x-azure-relay")])),
};

let frame = Attach {
source: Some(source),
target: Some(target),
};
assert!(to_value(&frame).is_ok());
}
}
Loading