use assert2::{assert, check};
use bytes::{Bytes, BytesMut};
use crate::{Decode, Encode, UnknownTaggedField, UnknownTaggedFields};
pub(crate) fn roundtrip<T>(message: &T, version: i16)
where
T: Encode + for<'de> Decode<'de> + PartialEq + std::fmt::Debug,
{
roundtrip_case(std::any::type_name::<T>(), message, version);
}
pub(crate) fn roundtrip_case<T>(label: &str, message: &T, version: i16)
where
T: Encode + for<'de> Decode<'de> + PartialEq + std::fmt::Debug,
{
let mut buf = BytesMut::new();
message.encode(&mut buf, version).unwrap();
check!(message.encoded_len(version) == buf.len(), "{label}");
let bytes = buf.freeze();
let mut cursor = &bytes[..];
let decoded = T::decode(&mut cursor, version).unwrap();
check!(cursor.is_empty(), "{label}");
check!(&decoded == message, "{label}");
let mut reencoded = BytesMut::new();
decoded.encode(&mut reencoded, version).unwrap();
check!(&reencoded[..] == &bytes[..], "{label}");
}
pub(crate) fn reject_truncated<T>(message: &T, version: i16)
where
T: Encode + for<'de> Decode<'de> + std::fmt::Debug,
{
let mut buf = BytesMut::new();
message.encode(&mut buf, version).unwrap();
let bytes = buf.freeze();
for end in 0..bytes.len() {
let mut cursor = &bytes[..end];
assert!(T::decode(&mut cursor, version).is_err());
}
}
pub(crate) fn unsupported_versions(min: i16, max: i16) -> Vec<i16> {
vec![min - 1, max + 1]
}
pub(crate) fn sample_tagged_fields() -> UnknownTaggedFields {
UnknownTaggedFields(vec![
UnknownTaggedField {
tag: 7,
bytes: Bytes::from_static(&[1, 2, 3]),
},
UnknownTaggedField {
tag: 11,
bytes: Bytes::from_static(&[4]),
},
])
}