Skip to content

Commit 4af58ce

Browse files
implemented decode for byte, short and int
1 parent 76fef58 commit 4af58ce

File tree

3 files changed

+224
-5
lines changed

3 files changed

+224
-5
lines changed

amqp-type/src/fixed_width/byte.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,43 @@
1+
use crate::error::AppError;
12
use crate::serde::encode::{Encode, Encoded};
3+
use crate::serde::decode::Decode;
4+
5+
const DEFAULT_CONSTR: u8 = 0x51;
26

37
impl Encode for i8 {
48
fn encode(&self) -> Encoded {
5-
Encoded::new_fixed(0x51, self.to_be_bytes().to_vec())
9+
Encoded::new_fixed(DEFAULT_CONSTR, self.to_be_bytes().to_vec())
10+
}
11+
}
12+
13+
impl Decode for i8 {
14+
fn can_decode(iter: impl Iterator<Item = u8>) -> bool {
15+
match iter.peekable().peek() {
16+
Some(&DEFAULT_CONSTR) => true,
17+
_ => false
18+
}
19+
}
20+
21+
fn try_decode(mut iter: impl Iterator<Item = u8>) -> Result<Self, crate::error::AppError>
22+
where
23+
Self: Sized {
24+
match iter.next() {
25+
Some(DEFAULT_CONSTR) => Ok(parse_i8(iter)?),
26+
Some(c) => Err(AppError::DeserializationIllegalConstructorError(c)),
27+
None => Err(AppError::IteratorEmptyOrTooShortError),
28+
}
629
}
730
}
831

32+
fn parse_i8(mut iter: impl Iterator<Item = u8>) -> Result<i8, AppError> {
33+
if let Some(val) = iter.next() {
34+
Ok(val as i8)
35+
} else {
36+
Err(AppError::IteratorEmptyOrTooShortError)
37+
}
38+
}
39+
40+
941
#[cfg(test)]
1042
mod test {
1143

@@ -16,4 +48,34 @@ mod test {
1648
let val: i8 = 8;
1749
assert_eq!(val.encode().constructor(), 0x51);
1850
}
51+
52+
#[test]
53+
fn can_decode_returns_true_if_constructor_is_valid() {
54+
let val = vec![0x51];
55+
assert_eq!(i8::can_decode(val.into_iter()), true);
56+
}
57+
58+
#[test]
59+
fn can_decode_return_false_if_constructor_is_invalid() {
60+
let val = vec![0x71];
61+
assert_eq!(i8::can_decode(val.into_iter()), false);
62+
}
63+
64+
#[test]
65+
fn try_decode_returns_correct_value() {
66+
let val = vec![0x51, 0x10];
67+
assert_eq!(i8::try_decode(val.into_iter()).unwrap(), 16);
68+
}
69+
70+
#[test]
71+
fn decode_returns_error_when_value_bytes_are_invalid() {
72+
let val = vec![0x66, 0x44];
73+
assert!(i8::try_decode(val.into_iter()).is_err());
74+
}
75+
76+
#[test]
77+
fn decode_returns_error_when_bytes_are_missing() {
78+
let val = vec![0x51];
79+
assert!(i8::try_decode(val.into_iter()).is_err());
80+
}
1981
}

amqp-type/src/fixed_width/int.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
use crate::serde::encode::{Encode, Encoded};
1+
use crate::{serde::encode::{Encode, Encoded}, error::AppError};
2+
use crate::serde::decode::Decode;
3+
use crate::verify::verify_bytes_read_eq;
4+
5+
const DEFAULT_CONSTR: u8 = 0x71;
6+
const SMALL_INT_CONSTR: u8 = 0x54;
27

38
impl Encode for i32 {
49
fn encode(&self) -> Encoded {
@@ -9,11 +14,98 @@ impl Encode for i32 {
914
}
1015
}
1116

17+
impl Decode for i32 {
18+
fn can_decode(iter: impl Iterator<Item = u8>) -> bool {
19+
match iter.peekable().peek() {
20+
Some(&DEFAULT_CONSTR) => true,
21+
Some(&SMALL_INT_CONSTR) => true,
22+
_ => false,
23+
}
24+
}
25+
26+
fn try_decode(mut iter: impl Iterator<Item = u8>) -> Result<Self, crate::error::AppError>
27+
where
28+
Self: Sized,
29+
{
30+
match iter.next() {
31+
Some(DEFAULT_CONSTR) => Ok(parse_i32(iter)?),
32+
Some(SMALL_INT_CONSTR) => Ok(parse_small_i32(iter)?),
33+
Some(c) => Err(AppError::DeserializationIllegalConstructorError(c)),
34+
None => Err(AppError::IteratorEmptyOrTooShortError),
35+
}
36+
}
37+
}
38+
39+
fn parse_i32(iter: impl Iterator<Item = u8>) -> Result<i32, AppError> {
40+
let mut val_bytes = [0; 4];
41+
let mut index = 0;
42+
for b in iter.take(4) {
43+
val_bytes[index] = b;
44+
index += 1;
45+
}
46+
verify_bytes_read_eq(index, 4)?;
47+
Ok(i32::from_be_bytes(val_bytes))
48+
}
49+
50+
fn parse_small_i32(mut iter: impl Iterator<Item = u8>) -> Result<i32, AppError> {
51+
if let Some(val) = iter.next() {
52+
Ok(val as i32)
53+
} else {
54+
Err(AppError::IteratorEmptyOrTooShortError)
55+
}
56+
}
57+
1258
#[cfg(test)]
1359
mod test {
1460

1561
use super::*;
1662

63+
64+
#[test]
65+
fn can_deocde_returns_true_if_constructor_is_valid() {
66+
let val = vec![0x71, 0x41];
67+
let small_val = vec![0x54, 0x41];
68+
assert_eq!(i32::can_decode(val.into_iter()), true);
69+
assert_eq!(i32::can_decode(small_val.into_iter()), true);
70+
}
71+
72+
#[test]
73+
fn can_decode_return_false_if_constructor_is_invalid() {
74+
let val = vec![0x70];
75+
assert_eq!(i32::can_decode(val.into_iter()), false);
76+
}
77+
78+
#[test]
79+
fn try_decode_returns_correct_value() {
80+
let val = vec![0x71, 0x00, 0x00, 0x00, 0x10];
81+
assert_eq!(i32::try_decode(val.into_iter()).unwrap(), 16)
82+
}
83+
84+
#[test]
85+
fn decode_returns_error_when_value_bytes_are_invalid() {
86+
let val = vec![0x56, 0x44];
87+
assert!(i32::try_decode(val.into_iter()).is_err());
88+
}
89+
90+
#[test]
91+
fn decode_returns_error_when_bytes_are_missing() {
92+
let val = vec![0x71, 0x01];
93+
assert!(i32::try_decode(val.into_iter()).is_err());
94+
}
95+
96+
97+
#[test]
98+
fn try_decode_can_decode_smallulong_values() {
99+
let val = vec![0x54, 0xff];
100+
assert_eq!(i32::try_decode(val.into_iter()).unwrap(), 255);
101+
}
102+
103+
#[test]
104+
fn try_decode_returns_error_when_parsing_small_ulong_and_bytes_are_missing() {
105+
let val = vec![0x54];
106+
assert!(i32::try_decode(val.into_iter()).is_err());
107+
}
108+
17109
#[test]
18110
fn construct_int() {
19111
let val = 500;

amqp-type/src/fixed_width/short.rs

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,84 @@
1+
use crate::error::AppError;
12
use crate::serde::encode::{Encode, Encoded};
3+
use crate::serde::decode::Decode;
4+
use crate::verify::verify_bytes_read_eq;
5+
6+
const DEFAULT_CONSTR: u8 = 0x61;
27

38
impl Encode for i16 {
49
fn encode(&self) -> Encoded {
510
Encoded::new_fixed(0x61, self.to_be_bytes().to_vec())
611
}
712
}
13+
impl Decode for i16 {
14+
fn can_decode(iter: impl Iterator<Item = u8>) -> bool {
15+
match iter.peekable().peek() {
16+
Some(&DEFAULT_CONSTR) => true,
17+
_ => false,
18+
}
19+
}
20+
21+
fn try_decode(mut iter: impl Iterator<Item = u8>) -> Result<Self, crate::error::AppError>
22+
where
23+
Self: Sized,
24+
{
25+
match iter.next() {
26+
Some(DEFAULT_CONSTR) => Ok(parse_i16(iter)?),
27+
Some(c) => Err(AppError::DeserializationIllegalConstructorError(c)),
28+
None => Err(AppError::IteratorEmptyOrTooShortError),
29+
}
30+
}
31+
}
32+
33+
fn parse_i16(iter: impl Iterator<Item = u8>) -> Result<i16, AppError> {
34+
let mut val_bytes = [0; 2];
35+
let mut index = 0;
36+
for b in iter.take(2) {
37+
val_bytes[index] = b;
38+
index += 1;
39+
}
40+
verify_bytes_read_eq(index, 2)?;
41+
Ok(i16::from_be_bytes(val_bytes))
42+
}
843

944
#[cfg(test)]
1045
mod test {
1146

1247
use super::*;
1348

1449
#[test]
15-
fn construct_short() {
16-
let val: i16 = 8;
50+
fn construct_ushort() {
51+
let val: i16 = 16;
1752
assert_eq!(val.encode().constructor(), 0x61);
1853
}
19-
}
54+
55+
#[test]
56+
fn can_deocde_returns_true_if_constructor_is_valid() {
57+
let val = vec![0x61, 0x41];
58+
assert_eq!(i16::can_decode(val.into_iter()), true);
59+
}
60+
61+
#[test]
62+
fn can_decode_return_false_if_constructor_is_invalid() {
63+
let val = vec![0x60];
64+
assert_eq!(i16::can_decode(val.into_iter()), false);
65+
}
66+
67+
#[test]
68+
fn try_decode_returns_correct_value() {
69+
let val = vec![0x61, 0x00, 0x10];
70+
assert_eq!(i16::try_decode(val.into_iter()).unwrap(), 16)
71+
}
72+
73+
#[test]
74+
fn decode_returns_error_when_value_bytes_are_invalid() {
75+
let val = vec![0x56, 0x44];
76+
assert!(i16::try_decode(val.into_iter()).is_err());
77+
}
78+
79+
#[test]
80+
fn decode_returns_error_when_bytes_are_missing() {
81+
let val = vec![0x61, 0x01];
82+
assert!(i16::try_decode(val.into_iter()).is_err());
83+
}
84+
}

0 commit comments

Comments
 (0)