#[macro_export]
macro_rules! impl_storable_bounded {
($ident:ident, $max_size:expr, $is_fixed_size:expr) => {
impl $crate::cdk::structures::storable::Storable for $ident {
const BOUND: $crate::cdk::structures::storable::Bound =
$crate::cdk::structures::storable::Bound::Bounded {
max_size: $max_size,
is_fixed_size: $is_fixed_size,
};
fn to_bytes(&self) -> ::std::borrow::Cow<'_, [u8]> {
let bytes = $crate::serialize::serialize(self).unwrap_or_else(|e| {
panic!("impl_storable_bounded: serialize failed: {e}");
});
::std::borrow::Cow::Owned(bytes)
}
fn into_bytes(self) -> Vec<u8> {
$crate::serialize::serialize(&self).unwrap_or_else(|e| {
panic!("impl_storable_bounded: serialize failed: {e}");
})
}
fn from_bytes(bytes: ::std::borrow::Cow<'_, [u8]>) -> Self {
$crate::serialize::deserialize(&bytes).unwrap_or_else(|e| {
panic!("impl_storable_bounded: deserialize failed: {e}");
})
}
}
};
}
#[macro_export]
macro_rules! impl_storable_unbounded {
($ident:ident) => {
impl $crate::cdk::structures::storable::Storable for $ident {
const BOUND: $crate::cdk::structures::storable::Bound =
$crate::cdk::structures::storable::Bound::Unbounded;
fn to_bytes(&self) -> ::std::borrow::Cow<'_, [u8]> {
let bytes = $crate::serialize::serialize(self).unwrap_or_else(|e| {
panic!("impl_storable_unbounded: serialize failed: {e}");
});
::std::borrow::Cow::Owned(bytes)
}
fn into_bytes(self) -> Vec<u8> {
$crate::serialize::serialize(&self).unwrap_or_else(|e| {
panic!("impl_storable_unbounded: serialize failed: {e}");
})
}
fn from_bytes(bytes: ::std::borrow::Cow<'_, [u8]>) -> Self {
$crate::serialize::deserialize(&bytes).unwrap_or_else(|e| {
panic!("impl_storable_unbounded: deserialize failed: {e}");
})
}
}
};
}
#[cfg(test)]
mod tests {
use canic_cdk::structures::storable::Storable;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
struct Sample {
v: u32,
}
impl_storable_bounded!(Sample, 32, false);
#[test]
fn bounded_round_trip() {
let s = Sample { v: 42 };
let bytes = s.to_bytes();
let decoded = Sample::from_bytes(bytes);
assert_eq!(decoded, s);
}
#[test]
#[should_panic(expected = "impl_storable_bounded: deserialize failed")]
fn bounded_deserialize_panics_with_context() {
let bytes = Cow::Owned(vec![0xFF]); let _ = Sample::from_bytes(bytes);
}
}