Skip to content

Commit 2f46e35

Browse files
naive implementation of list constructor
1 parent cccfd36 commit 2f46e35

File tree

4 files changed

+86
-51
lines changed

4 files changed

+86
-51
lines changed

amqp-lib/src/types/amqp_type.rs

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::error::AppError;
44
use crate::types::binary::Binary;
55
use crate::types::collection::*;
66
use crate::types::decimal::*;
7+
use crate::types::floating_point::*;
78
use bigdecimal::BigDecimal;
89
use indexmap::IndexMap;
910

@@ -20,6 +21,10 @@ pub struct Encoded {
2021
}
2122

2223
impl Encoded {
24+
pub fn new(constructor: u8, data: Option<Vec<u8>>) -> Self {
25+
Encoded { constructor, data }
26+
}
27+
2328
pub fn constructor(&self) -> u8 {
2429
self.constructor
2530
}
@@ -51,8 +56,6 @@ pub struct Described();
5156
pub struct Constructor(u8);
5257
#[derive(Hash, Eq, PartialEq)]
5358
pub struct Timestamp(u64);
54-
pub struct Float(f32);
55-
pub struct Double(f64);
5659

5760
#[derive(Hash, Eq, PartialEq)]
5861
pub enum AmqpType {
@@ -113,40 +116,6 @@ impl Encode for AmqpType {
113116
}
114117
}
115118

116-
impl Hash for Float {
117-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
118-
self.0.to_bits().hash(state)
119-
}
120-
}
121-
122-
impl Hash for Double {
123-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
124-
self.0.to_bits().hash(state)
125-
}
126-
}
127-
128-
impl PartialEq for Float {
129-
fn eq(&self, other: &Self) -> bool {
130-
self.0.to_bits() == other.0.to_bits()
131-
}
132-
133-
fn ne(&self, other: &Self) -> bool {
134-
!self.eq(other)
135-
}
136-
}
137-
138-
impl Eq for Float {}
139-
140-
impl PartialEq for Double {
141-
fn eq(&self, other: &Self) -> bool {
142-
self.0.to_bits() == self.0.to_bits()
143-
}
144-
145-
fn ne(&self, other: &Self) -> bool {
146-
!self.eq(other)
147-
}
148-
}
149-
150119
impl Eq for Double {}
151120
impl From<u8> for Constructor {
152121
fn from(value: u8) -> Self {
@@ -267,7 +236,9 @@ impl Encode for i64 {
267236
impl Encode for String {
268237
fn encode(&self) -> Encoded {
269238
match self.len() {
270-
x if x >= 0 as usize && x <= 255 as usize => 0xa1.into(),
239+
x if x >= 0 as usize && x <= 255 as usize => {
240+
Encoded::new(0xa1, Some(self.as_bytes().to_vec()))
241+
}
271242
_ => 0xb1.into(),
272243
}
273244
}
@@ -348,23 +319,13 @@ impl From<Float> for AmqpType {
348319
}
349320
}
350321

351-
impl From<f32> for Float {
352-
fn from(value: f32) -> Self {
353-
Float(value)
354-
}
355-
}
356322

357323
impl From<Double> for AmqpType {
358324
fn from(value: Double) -> Self {
359325
AmqpType::Double(value.into())
360326
}
361327
}
362328

363-
impl From<f64> for Double {
364-
fn from(value: f64) -> Self {
365-
Double(value)
366-
}
367-
}
368329

369330
impl From<char> for AmqpType {
370331
fn from(value: char) -> Self {
@@ -673,4 +634,15 @@ mod tests {
673634
let val = AmqpType::Array(arr.into());
674635
assert_eq!(val.encode().constructor(), 0xf0);
675636
}
637+
638+
#[test]
639+
fn amqp_type_can_construct_array_with_less_than_255_elements_and_larger_than_255_bytes() {
640+
let mut arr = vec![];
641+
for i in 0..100 {
642+
arr.push("aaaaaaaaaaaaaaaaaaaa".into());
643+
}
644+
let val = AmqpType::Array(arr.into());
645+
assert_eq!(val.encode().constructor(), 0xe0);
646+
647+
}
676648
}

amqp-lib/src/types/collection.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ pub struct Map(IndexMap<AmqpType, AmqpType>);
1313

1414
impl Encode for List {
1515
fn encode(&self) -> Encoded {
16-
let encoded_list: Vec<Encoded> = self.0.iter().map(|x| x.encode()).collect();
17-
let byte_size = encoded_list.iter().fold(0, |acc, x| acc + x.data_len());
18-
match (encoded_list.len(), byte_size) {
16+
let encoded: Vec<Encoded> = self.0.iter().map(|x| x.encode()).collect();
17+
let byte_size = encoded.iter().fold(0, |acc, x| acc + x.data_len());
18+
match (encoded.len(), byte_size) {
1919
(0, _) => 0x45.into(),
2020
(len, size) if len <= 255 && size < 256 => 0xc0.into(),
2121
(_, _) => 0xd0.into(),
@@ -31,7 +31,13 @@ impl Encode for Map {
3131

3232
impl Encode for Array {
3333
fn encode(&self) -> Encoded {
34-
todo!()
34+
let encoded: Vec<Encoded> = self.0.iter().map(|x| x.encode()).collect();
35+
let byte_size = encoded.iter().fold(0, |acc, x| acc + x.data_len());
36+
match (encoded.len(), byte_size) {
37+
(len, size) if len <= 255 && size < 256 => 0xe0.into(),
38+
(_, _) => 0xf0.into(),
39+
}
40+
3541
}
3642
}
3743

amqp-lib/src/types/floating_point.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use std::hash::Hash;
2+
3+
pub struct Float(f32);
4+
pub struct Double(f64);
5+
6+
/// Crate assumes nothing about the values being passed to it.
7+
/// Any kind of f32 value is handled as is.
8+
/// This means that the hash function considers only the bytes of a float.
9+
/// Two f32 or f64 values are considered Equal if and only if, the entirety of their by sequences match.
10+
/// This ensures that no information is lost.
11+
/// regardless of whether they mean Nan or similar things.
12+
/// As a result, Nan == Nan if and only if the two numbers have the exact same byte sequence.
13+
impl Hash for Float {
14+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
15+
self.0.to_bits().hash(state)
16+
}
17+
}
18+
19+
impl Hash for Double {
20+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
21+
self.0.to_bits().hash(state)
22+
}
23+
}
24+
25+
impl PartialEq for Float {
26+
fn eq(&self, other: &Self) -> bool {
27+
self.0.to_bits() == other.0.to_bits()
28+
}
29+
30+
fn ne(&self, other: &Self) -> bool {
31+
!self.eq(other)
32+
}
33+
}
34+
35+
impl Eq for Float {}
36+
37+
impl PartialEq for Double {
38+
fn eq(&self, other: &Self) -> bool {
39+
self.0.to_bits() == self.0.to_bits()
40+
}
41+
42+
fn ne(&self, other: &Self) -> bool {
43+
!self.eq(other)
44+
}
45+
}
46+
47+
impl From<f32> for Float {
48+
fn from(value: f32) -> Self {
49+
Float(value)
50+
}
51+
}
52+
impl From<f64> for Double {
53+
fn from(value: f64) -> Self {
54+
Double(value)
55+
}
56+
}

amqp-lib/src/types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pub mod amqp_type;
22
pub mod binary;
33
pub mod collection;
44
pub mod decimal;
5+
pub mod floating_point;

0 commit comments

Comments
 (0)