use bytes::{Bytes, BytesMut};
use crate::{v1::Flags, v2::Tag, Version};
macro_rules! bytes {
($($item:expr),* $(,)?) => {
{
#[allow(unused_mut)]
let mut buffer: ::bytes::BytesMut = ::bytes::BytesMut::new();
$(
#[allow(clippy::identity_op)]
$crate::macros::ToBytes::to_bytes(&$item, &mut buffer);
)*
buffer.freeze()
}
};
}
pub(crate) trait ToBytes {
fn to_bytes(&self, buffer: &mut BytesMut);
}
impl ToBytes for [u8] {
fn to_bytes(&self, buffer: &mut BytesMut) {
buffer.extend_from_slice(self);
}
}
impl<const N: usize> ToBytes for [u8; N] {
fn to_bytes(&self, buffer: &mut BytesMut) {
buffer.extend_from_slice(self);
}
}
impl ToBytes for str {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_bytes().to_bytes(buffer);
}
}
impl<T: ToBytes + ?Sized> ToBytes for &T {
fn to_bytes(&self, buffer: &mut BytesMut) {
(**self).to_bytes(buffer);
}
}
impl ToBytes for u8 {
fn to_bytes(&self, buffer: &mut BytesMut) {
[*self].to_bytes(buffer);
}
}
impl ToBytes for Tag {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_u8().to_bytes(buffer);
}
}
impl ToBytes for Vec<u8> {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_slice().to_bytes(buffer);
}
}
impl ToBytes for Bytes {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_ref().to_bytes(buffer);
}
}
impl ToBytes for Version {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.0.to_bytes(buffer);
}
}
impl ToBytes for BytesMut {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_ref().to_bytes(buffer);
}
}
impl ToBytes for Flags {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.as_bytes().to_bytes(buffer);
}
}
macro_rules! impl_to_bytes_le {
($( $type:ty ),* $(,)?) => {
$(
impl ToBytes for $type {
fn to_bytes(&self, buffer: &mut BytesMut) {
self.to_le_bytes().to_bytes(buffer);
}
}
)*
};
}
impl_to_bytes_le!(u16, u32);
macro_rules! assert_bytes_eq {
($lhs:expr, $rhs:expr, $msg:literal $( $tokens:tt)*) => {{
let lhs = &$lhs[..];
let rhs = &$rhs[..];
if lhs != rhs {
let lhs: Vec<_> = hexdump::hexdump_iter(lhs)
.map(|line| line.to_string())
.collect();
let rhs: Vec<_> = hexdump::hexdump_iter(rhs)
.map(|line| line.to_string())
.collect::<Vec<_>>();
pretty_assertions::assert_eq!(lhs.join("\n"), rhs.join("\n"), $msg $($tokens)*);
}
}};
($lhs:expr, $rhs:expr) => {
assert_bytes_eq!($lhs, $rhs, "{} != {}", stringify!($lhs), stringify!($rhs));
};
}
macro_rules! dir_map {
( $( $key:expr => $value:expr ),* $(,)?) => {
$crate::v2::write::Directory {
children: [
$(
($key.parse().unwrap(), $crate::v2::write::DirEntry::from($value))
),*
]
.into_iter()
.collect(),
}
};
}