Skip to content

Commit 1406316

Browse files
implemented decode for decimal32
1 parent 6b0e913 commit 1406316

File tree

1 file changed

+80
-3
lines changed

1 file changed

+80
-3
lines changed

amqp-type/src/fixed_width/decimal32.rs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use std::hash::{Hash, Hasher};
2+
use crate::error::AppError;
3+
use crate::serde::decode::Decode;
24

35
use crate::serde::encode::{Encode, Encoded};
6+
use crate::verify::verify_bytes_read_eq;
47

58
// 7 digits
69
const DEFAULT_CONSTR: u8 = 0x74;
710

11+
#[derive(Debug)]
812
pub struct Decimal32(f32);
913

1014
impl Encode for Decimal32 {
@@ -16,6 +20,34 @@ impl Encode for Decimal32 {
1620
}
1721
}
1822

23+
impl Decode for Decimal32 {
24+
fn can_decode(iter: impl Iterator<Item=u8>) -> bool {
25+
match iter.peekable().peek() {
26+
Some(&DEFAULT_CONSTR) => true,
27+
_ => false,
28+
}
29+
}
30+
31+
fn try_decode(mut iter: impl Iterator<Item=u8>) -> Result<Self, AppError> where Self: Sized {
32+
match iter.next() {
33+
Some(DEFAULT_CONSTR) => Ok(parse_decimal32(iter)?),
34+
Some(c) => Err(AppError::DeserializationIllegalConstructorError(c)),
35+
None => Err(AppError::IteratorEmptyOrTooShortError),
36+
}
37+
}
38+
}
39+
40+
fn parse_decimal32(iter: impl Iterator<Item=u8>) -> Result<Decimal32, AppError> {
41+
let mut byte_vals = [0; 4];
42+
let mut index = 0;
43+
for b in iter.take(4) {
44+
byte_vals[index] = b;
45+
index += 1;
46+
}
47+
verify_bytes_read_eq(index, 4)?;
48+
Ok(Decimal32(f32::from_be_bytes(byte_vals)))
49+
}
50+
1951
impl Hash for Decimal32 {
2052
fn hash<H: Hasher>(&self, state: &mut H) {
2153
self.0.to_bits().hash(state)
@@ -42,6 +74,7 @@ fn encode_to_bytes(value: &f32) -> u32 {
4274

4375
#[cfg(test)]
4476
mod test {
77+
use bytes::BufMut;
4578
use super::*;
4679

4780
#[test]
@@ -68,10 +101,16 @@ mod test {
68101

69102
#[test]
70103
fn test_large_number() {
71-
let decimal = 3.4028235e38; // Max value for f32
104+
let decimal = f32::MAX; // Max value for f32
72105
let encoded = encode_to_bytes(&decimal);
73-
let expected = 0b01111111011111111111111111111111;
74-
assert_eq!(encoded, expected);
106+
assert_eq!(encoded, decimal.to_bits());
107+
}
108+
109+
#[test]
110+
fn test_small_number() {
111+
let decimal = f32::MIN; // Max value for f32
112+
let encoded = encode_to_bytes(&decimal);
113+
assert_eq!(encoded, decimal.to_bits());
75114
}
76115

77116
#[test]
@@ -113,4 +152,42 @@ mod test {
113152
let expected = 0b11111111100000000000000000000000; // Negative infinity in f32
114153
assert_eq!(encoded, expected);
115154
}
155+
156+
#[test]
157+
fn test_successful_deserialization() {
158+
let value = 1.2345f32;
159+
let mut data = vec![DEFAULT_CONSTR];
160+
data.put_f32(value);
161+
let mut iter = data.into_iter();
162+
163+
match Decimal32::try_decode(&mut iter) {
164+
Ok(decimal) => assert_eq!(value, decimal.0),
165+
Err(e) => panic!("Unexpected error: {:?}", e),
166+
}
167+
}
168+
169+
#[test]
170+
fn test_illegal_constructor_deserialization() {
171+
let illegal_constructor = 0xFF;
172+
let bytes = vec![illegal_constructor, /* other bytes */];
173+
let mut iter = bytes.into_iter();
174+
175+
match Decimal32::try_decode(&mut iter) {
176+
Ok(_) => panic!("Expected an error, but deserialization succeeded"),
177+
Err(AppError::DeserializationIllegalConstructorError(c)) => assert_eq!(illegal_constructor, c),
178+
Err(e) => panic!("Unexpected error type: {:?}", e),
179+
}
180+
}
181+
182+
#[test]
183+
fn test_empty_iterator_deserialization() {
184+
let bytes = vec![]; // Empty vector
185+
let mut iter = bytes.into_iter();
186+
187+
match Decimal32::try_decode(&mut iter) {
188+
Ok(_) => panic!("Expected an error, but deserialization succeeded"),
189+
Err(AppError::IteratorEmptyOrTooShortError) => (), // Expected outcome
190+
Err(e) => panic!("Unexpected error type: {:?}", e),
191+
}
192+
}
116193
}

0 commit comments

Comments
 (0)