1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
use core::marker::PhantomData;
use crate::{
buffer::Buffer,
deserialize::{Deserialize, DeserializeError, Deserializer},
formula::{BareFormula, Formula},
serialize::{Serialize, Sizes},
};
/// Formula type that mirrors specified formula `F`.
/// It can be used to turn unsized field type into sized one,
/// keeping the same formula.
///
/// # Example
///
/// ```compile_fail
/// # use alkahest::*;
/// type MyFormula = [str]; // Slice element type must be sized. `str` is unsized.
///
/// let mut buffer = [0u8; 22];
/// serialize::<MyFormula, _>(["qwe", "rty"], &mut buffer).unwrap();
/// ```
///
/// // Wrap usized type into `As`
///
/// ```
/// # use alkahest::*;
/// type MyFormula = [As<str>]; // `As` is always size.
///
/// # #[cfg(feature = "fixed8")]
/// # let mut buffer = [0u8; 10];
///
/// # #[cfg(feature = "fixed16")]
/// # let mut buffer = [0u8; 14];
///
/// # #[cfg(feature = "fixed32")]
/// let mut buffer = [0u8; 22];
///
/// # #[cfg(feature = "fixed64")]
/// # let mut buffer = [0u8; 38];
/// serialize::<MyFormula, _>(["qwe", "rty"], &mut buffer).unwrap();
/// ```
pub struct As<F: ?Sized> {
marker: PhantomData<fn(&F) -> &F>,
}
impl<F> Formula for As<F>
where
F: BareFormula + ?Sized,
{
const MAX_STACK_SIZE: Option<usize> = F::MAX_STACK_SIZE;
const EXACT_SIZE: bool = F::EXACT_SIZE;
const HEAPLESS: bool = F::HEAPLESS;
}
impl<F, T> Serialize<As<F>> for T
where
F: BareFormula + ?Sized,
T: Serialize<F>,
{
#[inline(always)]
fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
where
Self: Sized,
B: Buffer,
{
<T as Serialize<F>>::serialize(self, sizes, buffer)
}
#[inline(always)]
fn size_hint(&self) -> Option<Sizes> {
<T as Serialize<F>>::size_hint(self)
}
}
impl<'de, F, T> Deserialize<'de, As<F>> for T
where
F: BareFormula + ?Sized,
T: Deserialize<'de, F>,
{
#[inline(always)]
fn deserialize(deserializer: Deserializer<'de>) -> Result<Self, DeserializeError>
where
Self: Sized,
{
<T as Deserialize<'de, F>>::deserialize(deserializer)
}
#[inline(always)]
fn deserialize_in_place(
&mut self,
deserializer: Deserializer<'de>,
) -> Result<(), DeserializeError> {
<T as Deserialize<'de, F>>::deserialize_in_place(self, deserializer)
}
}