mod decode;
mod encode;
pub use decode::{DecodeLimits, Decoder, TaggedField};
pub use encode::Encoder;
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::{DecodeLimits, Decoder, Encoder};
use crate::Error;
#[test]
fn encodes_and_decodes_fixed_width_primitives() {
let mut encoder = Encoder::new();
encoder.write_bool(true);
encoder.write_i16(0x1234);
encoder.write_i32(0x1234_5678);
encoder.write_i64(0x0102_0304_0506_0708);
encoder.write_f64(123.5);
let bytes = encoder.into_bytes();
assert_eq!(
bytes,
[
1, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x40, 0x5e, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);
let mut decoder = Decoder::new(&bytes);
assert!(decoder.read_bool().unwrap());
assert_eq!(decoder.read_i16().unwrap(), 0x1234);
assert_eq!(decoder.read_i32().unwrap(), 0x1234_5678);
assert_eq!(decoder.read_i64().unwrap(), 0x0102_0304_0506_0708);
assert_eq!(decoder.read_f64().unwrap(), 123.5);
assert!(decoder.is_empty());
}
#[test]
fn encodes_and_decodes_nullable_strings_and_bytes() {
let mut encoder = Encoder::new();
encoder.write_nullable_string(Some("topic")).unwrap();
encoder.write_nullable_string(None).unwrap();
encoder.write_nullable_bytes(Some(&[1, 2, 3])).unwrap();
encoder.write_nullable_bytes(None).unwrap();
let bytes = encoder.into_bytes();
let mut decoder = Decoder::new(&bytes);
assert_eq!(
decoder.read_nullable_string().unwrap(),
Some("topic".to_owned())
);
assert_eq!(decoder.read_nullable_string().unwrap(), None);
assert_eq!(decoder.read_nullable_bytes().unwrap(), Some(vec![1, 2, 3]));
assert_eq!(decoder.read_nullable_bytes().unwrap(), None);
assert!(decoder.is_empty());
}
#[test]
fn encodes_and_decodes_compact_types_and_empty_tags() {
let mut encoder = Encoder::new();
encoder.write_unsigned_varint(300);
encoder.write_compact_string("kafka").unwrap();
encoder.write_compact_nullable_string(None).unwrap();
encoder.write_compact_bytes(&[9, 8]).unwrap();
encoder.write_empty_tagged_fields();
let bytes = encoder.into_bytes();
let mut decoder = Decoder::new(&bytes);
assert_eq!(decoder.read_unsigned_varint().unwrap(), 300);
assert_eq!(decoder.read_compact_string().unwrap(), "kafka");
assert_eq!(decoder.read_compact_nullable_string().unwrap(), None);
assert_eq!(decoder.read_compact_bytes().unwrap(), vec![9, 8]);
assert_eq!(decoder.read_tagged_fields().unwrap(), Vec::new());
assert!(decoder.is_empty());
}
#[test]
fn decodes_signed_varints() {
let mut decoder = Decoder::new(&[0x02, 0x01, 0x04, 0x03]);
assert_eq!(decoder.read_varint().unwrap(), 1);
assert_eq!(decoder.read_varint().unwrap(), -1);
assert_eq!(decoder.read_varlong().unwrap(), 2);
assert_eq!(decoder.read_varlong().unwrap(), -2);
assert!(decoder.is_empty());
}
#[test]
fn rejects_invalid_bool_and_short_input() {
let mut decoder = Decoder::new(&[2]);
assert_eq!(decoder.read_bool(), Err(Error::InvalidBool(2)));
let mut decoder = Decoder::new(&[0]);
assert!(matches!(
decoder.read_i16(),
Err(Error::UnexpectedEof {
needed: 2,
remaining: 1
})
));
}
#[test]
fn rejects_arrays_before_allocating_above_the_configured_limit() {
let limits = DecodeLimits::new().with_max_array_elements(2);
let array_length = 3_i32.to_be_bytes();
let mut decoder = Decoder::with_limits(&array_length, limits);
assert_eq!(
decoder.read_array("test array", |_| Ok(())).unwrap_err(),
Error::LimitExceeded {
kind: "test array",
actual: 3,
max: 2,
}
);
let mut decoder = Decoder::with_limits(&[4], limits);
assert_eq!(
decoder
.read_compact_array("compact test array", |_| Ok(()))
.unwrap_err(),
Error::LimitExceeded {
kind: "compact test array",
actual: 3,
max: 2,
}
);
let mut decoder = Decoder::with_limits(&[3], limits);
assert_eq!(
decoder.read_tagged_fields().unwrap_err(),
Error::LimitExceeded {
kind: "tagged fields",
actual: 3,
max: 2,
}
);
}
}