use crate::MutationType;
use crate::Node;
use crate::Visitor;
use parity_scale_codec::{Compact, Decode, Encode};
use serde::{Deserialize, Serialize};
use std::collections::VecDeque;
#[derive(Debug, Clone, Encode, Decode, Serialize, Deserialize)]
pub struct Compactu16(#[codec(compact)] pub u16);
#[derive(Debug, Clone, Encode, Decode, Serialize, Deserialize)]
pub struct Compactu32(#[codec(compact)] pub u32);
#[derive(Debug, Clone, Encode, Decode, Serialize, Deserialize)]
pub struct Compactu64(#[codec(compact)] pub u64);
#[derive(Debug, Clone, Encode, Decode, Serialize, Deserialize)]
pub struct Compactu128(#[codec(compact)] pub u128);
macro_rules! impl_generate_compact {
($type: ty, $inner: ty, $num_bytes: literal) => {
impl Node for $type {
fn __autarkie_generate(
v: &mut crate::Visitor,
depth: &mut usize,
cur_depth: usize,
settings: Option<crate::GenerateSettings>,
) -> Option<Self> {
let Some(compacted) = crate::maybe_deserialize::<Compact<$inner>>(
&mut v.generate_bytes($num_bytes).as_slice(),
) else {
return None;
};
Some(Self(compacted.0))
}
fn __autarkie_cmps(
&self,
v: &mut crate::Visitor,
index: usize,
__autarkie_val: (u64, u64),
) {
if __autarkie_val.0 == self.0 as u64 {
v.register_cmp(crate::serialize(&(__autarkie_val.1 as $inner)));
};
}
fn __autarkie_mutate(
&mut self,
ty: &mut MutationType,
visitor: &mut Visitor,
path: VecDeque<usize>,
) {
debug_assert!(path.len() == 0);
match ty {
MutationType::Splice(other) => {
if let Some(compacted) = crate::maybe_deserialize::<Compact<$inner>>(other)
{
*self = Self(compacted.0);
}
}
MutationType::GenerateReplace(ref mut bias) => {
if let Some(generated) = Self::__autarkie_generate(visitor, bias, 0, None) {
*self = generated;
visitor.add_serialized(crate::serialize(self), Self::__autarkie_id());
}
}
_ => {
unreachable!()
}
}
}
}
};
}
impl_generate_compact!(Compactu16, u16, 2);
impl_generate_compact!(Compactu32, u32, 4);
impl_generate_compact!(Compactu64, u64, 8);
impl_generate_compact!(Compactu128, u128, 32);