use macro_rules_attribute::derive;
use mini_macro_magic::export;
#[derive(export!)]
#[custom(export(person$))]
pub struct Person {
name: String,
age: u8,
}
#[derive(export!)]
#[custom(export(other_person$))]
pub struct OtherPerson {
age: u8, name: String,
}
person!(impl_serialize!(Person));
other_person!(impl_serialize!(OtherPerson));
#[test]
fn check_serialization() {
let bob = Person {
name: "bob".into(),
age: 29,
};
let mut bytes = Vec::new();
bob.serialize(&mut bytes);
assert_eq!(bytes, [3, 0, 0, 0, 0, 0, 0, 0, 98, 111, 98, 29]);
}
#[test]
fn check_other_serialization() {
let bob = OtherPerson {
name: "bob".into(),
age: 29,
};
let mut bytes = Vec::new();
bob.serialize(&mut bytes);
assert_eq!(bytes, [29, 3, 0, 0, 0, 0, 0, 0, 0, 98, 111, 98]);
}
macro_rules! impl_serialize {
{{
$(#[$($attr:tt)*])*
$vis:vis struct $name:ident {
$($field:ident: $ty:ty),*$(,)?
}
} $path:path} => {
impl Serialize for $path {
fn serialize(&self, buffer: &mut Vec<u8>) {
$(self.$field.serialize(buffer);)*
}
}
};
}
use impl_serialize;
trait Serialize {
fn serialize(&self, buffer: &mut Vec<u8>);
}
impl Serialize for u8 {
fn serialize(&self, buffer: &mut Vec<u8>) {
buffer.push(*self);
}
}
impl Serialize for usize {
fn serialize(&self, buffer: &mut Vec<u8>) {
buffer.extend((*self as u64).to_le_bytes());
}
}
impl Serialize for String {
fn serialize(&self, buffer: &mut Vec<u8>) {
self.len().serialize(buffer);
buffer.extend(self.as_bytes());
}
}