diff options
Diffstat (limited to 'src/protocol.rs')
-rw-r--r-- | src/protocol.rs | 121 |
1 files changed, 119 insertions, 2 deletions
diff --git a/src/protocol.rs b/src/protocol.rs index 01265df..e768fdb 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -13,6 +13,7 @@ pub struct ProtocolPacketSpec { pub direction: String, pub id: i32, pub name: String, + pub body_struct: String, pub fields: Vec<ProtocolPacketField>, } @@ -35,7 +36,7 @@ pub trait Packet<I: PacketIdentifier>: Serialize { #[derive(Debug)] pub enum PacketErr { UnknownId(i32), - DeserializeFailed(DeserializeErr) + DeserializeFailed(DeserializeErr), } #[derive(Debug, Clone, PartialEq)] @@ -48,6 +49,11 @@ pub trait ProtocolType: Serialize + Deserialize {} impl<T: Serialize + Deserialize> ProtocolType for T {} +#[cfg(test)] +pub trait TestRandom { + fn test_gen_random() -> Self; +} + #[macro_export] macro_rules! as_item { ($i:item) => { $i }; @@ -82,6 +88,13 @@ macro_rules! __protocol_body_def_helper { Deserialized::ok(Self::default(), data) } } + + #[cfg(test)] + impl TestRandom for $bodyt { + fn test_gen_random() -> Self { + Self::default() + } + } }; ($bodyt: ident { $($fname: ident: $ftyp: ty ),+ }) => { $crate::as_item! { @@ -107,6 +120,13 @@ macro_rules! __protocol_body_def_helper { Deserialized::ok(Self{ $($fname),+ }, _rest) } } + + #[cfg(test)] + impl TestRandom for $bodyt { + fn test_gen_random() -> Self { + Self{ $($fname: <$ftyp>::test_gen_random()),+ } + } + } } } @@ -189,6 +209,7 @@ macro_rules! define_protocol { direction: stringify!($direction).to_owned(), id: $id, name: stringify!($nam).to_owned(), + body_struct: stringify!($body).to_owned(), fields: vec!( $(crate::protocol::ProtocolPacketField{ name: stringify!($fnam).to_owned(), @@ -206,6 +227,13 @@ macro_rules! define_protocol { } #[macro_export] +macro_rules! count_num { + () => { 0 }; + ($item: tt) => { 1 }; + ($item: tt, $($rest: tt),+) => { 1 + count_num!($($rest),+) } +} + +#[macro_export] macro_rules! proto_enum_with_type { ($typ: ty, $from_nam: ident, $as_nam: ident, $fmt: literal, $typname: ident, $(($bval: literal, $nam: ident)),*) => { $crate::as_item! { @@ -274,6 +302,20 @@ macro_rules! proto_enum_with_type { (*self).into() } } + + #[cfg(test)] + impl TestRandom for $typname { + fn test_gen_random() -> Self { + let mut idx: usize = (rand::random::<usize>() % (count_num!($($bval),+))) + 1; + $( + idx -= 1; + if idx == 0 { + return $typname::$nam; + } + )+ + panic!("cannot generate random {}", stringify!($typname)); + } + } } } @@ -345,5 +387,80 @@ macro_rules! proto_byte_flag { Ok(u8::mc_deserialize(data)?.map(move |b| $typname(b))) } } + + #[cfg(test)] + impl TestRandom for $typname { + fn test_gen_random() -> Self { + let mut out = <$typname>::default(); + $(paste::paste! { + out.[<set_ $nam>](rand::random::<bool>()); + })+ + out + } + } } -}
\ No newline at end of file +} + +#[macro_export] +macro_rules! counted_array_type { + ($name: ident, $countert: ty, $tousize_fn: ident, $fromusize_fn: ident) => { + #[derive(Debug, Clone, PartialEq)] + pub struct $name<T> where T: Debug + Clone + PartialEq { + pub data: Vec<T> + } + + impl<T> Serialize for $name<T> where T: Serialize + Debug + Clone + PartialEq { + fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { + let count: $countert = $fromusize_fn(self.data.len()); + to.serialize_other(&count)?; + + for entry in &self.data { + to.serialize_other(entry)?; + } + + Ok(()) + } + } + + impl<T> Deserialize for $name<T> where T: Deserialize + Debug + Clone + PartialEq { + fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { + let Deserialized{value: raw_count, mut data} = <$countert>::mc_deserialize(data)?; + let count: usize = $tousize_fn(raw_count); + + let mut out = Vec::with_capacity(count); + for _ in 0..count { + let Deserialized{value: next, data: rest} = T::mc_deserialize(data)?; + data = rest; + out.push(next); + } + + Deserialized::ok(Self { data: out }, data) + } + } + + impl<T> Into<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { + fn into(self) -> Vec<T> { + self.data + } + } + + impl<T> From<Vec<T>> for $name<T> where T: Debug + Clone + PartialEq { + fn from(data: Vec<T>) -> Self { + Self { data } + } + } + + #[cfg(test)] + impl<T> TestRandom for $name<T> where T: TestRandom + Debug + Clone + PartialEq { + fn test_gen_random() -> Self { + let elem_count: usize = rand::random::<usize>() % 32; + let mut out = Vec::with_capacity(elem_count); + for _ in 0..elem_count { + out.push(T::test_gen_random()); + } + + Self { data: out } + } + } + } +} |