|
|
|
@ -370,9 +370,15 @@ macro_rules! common_impl {
|
|
|
|
|
}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! define_encode_str {
|
|
|
|
|
($name:ident$(<$N:ident>)?($in:ty) $(where $( $where:tt )+)?) => {
|
|
|
|
|
fn $name$(<const $N: usize>)?(src: $in) -> String $( where $( $where )+ )?;
|
|
|
|
|
macro_rules! define_encode {
|
|
|
|
|
($name:ident$(<$N:ident>)?($in:ty) {
|
|
|
|
|
str => $str:ident,
|
|
|
|
|
write => $write:ident
|
|
|
|
|
$(,)?
|
|
|
|
|
} $(where $( $where:tt )+)?) => {
|
|
|
|
|
fn $str$(<const $N: usize>)?(src: $in) -> String $( where $( $where )+ )?;
|
|
|
|
|
|
|
|
|
|
fn $write$(<const $N: usize>)?(w: impl std::fmt::Write, src: $in) -> std::fmt::Result $( where $( $where )+ )?;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -386,6 +392,42 @@ macro_rules! impl_encode_str {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! impl_encode_write {
|
|
|
|
|
($name:ident$(<$N:ident>)?($in:ty) => $impl:ident (|$bytes:ident| $into_slice:expr) $(where $( $where:tt )+)?) => {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn $name$(<const $N: usize>)?(mut w: impl std::fmt::Write, src: $in) -> std::fmt::Result $( where $( $where )+ )? {
|
|
|
|
|
let $bytes = Self::$impl(src);
|
|
|
|
|
let s = unsafe { std::str::from_utf8_unchecked($into_slice) };
|
|
|
|
|
w.write_str(s)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct DisplaySized<'a, E: Encode + ?Sized, const N: usize>(&'a [u8; N], std::marker::PhantomData<E>);
|
|
|
|
|
pub struct DisplaySizedHeap<'a, E: Encode + ?Sized, const N: usize>(&'a [u8; N], std::marker::PhantomData<E>);
|
|
|
|
|
pub struct DisplaySlice<'a, E: Encode + ?Sized>(&'a [u8], std::marker::PhantomData<E>);
|
|
|
|
|
|
|
|
|
|
impl<'a, E: Encode, const N: usize> std::fmt::Display for DisplaySized<'a, E, N> where [u8; N * 2]: {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
E::write_sized(f, self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, E: Encode, const N: usize> std::fmt::Display for DisplaySizedHeap<'a, E, N> where [u8; N * 2]: {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
E::write_sized_heap(f, self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, E: Encode> std::fmt::Display for DisplaySlice<'a, E> {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
E::write_slice(f, self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub trait Encode {
|
|
|
|
|
/// Encodes the sized input on the stack.
|
|
|
|
|
fn enc_sized<const N: usize>(src: &[u8; N]) -> [u8; N * 2]
|
|
|
|
@ -400,9 +442,31 @@ pub trait Encode {
|
|
|
|
|
/// Encodes the unsized input on the heap.
|
|
|
|
|
fn enc_slice(src: &[u8]) -> Box<[u8]>;
|
|
|
|
|
|
|
|
|
|
define_encode_str!(enc_str_sized<N>(&[u8; N]) where [u8; N * 2]:);
|
|
|
|
|
define_encode_str!(enc_str_sized_heap<N>(&[u8; N]) where [u8; N * 2]:);
|
|
|
|
|
define_encode_str!(enc_str_slice(&[u8]));
|
|
|
|
|
define_encode!(enc_sized<N>(&[u8; N]) {
|
|
|
|
|
str => enc_str_sized,
|
|
|
|
|
write => write_sized,
|
|
|
|
|
} where [u8; N * 2]:);
|
|
|
|
|
define_encode!(enc_sized_heap<N>(&[u8; N]) {
|
|
|
|
|
str => enc_str_sized_heap,
|
|
|
|
|
write => write_sized_heap,
|
|
|
|
|
} where [u8; N * 2]:);
|
|
|
|
|
define_encode!(enc_slice(&[u8]) {
|
|
|
|
|
str => enc_str_slice,
|
|
|
|
|
write => write_slice,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/// Returns an `impl Display` of the sized input on the stack.
|
|
|
|
|
fn display_sized<const N: usize>(src: &[u8; N]) -> DisplaySized<'_, Self, N>
|
|
|
|
|
where
|
|
|
|
|
[u8; N * 2]:;
|
|
|
|
|
|
|
|
|
|
/// Returns an `impl Display` of the sized input on the heap.
|
|
|
|
|
fn display_sized_heap<const N: usize>(src: &[u8; N]) -> DisplaySizedHeap<'_, Self, N>
|
|
|
|
|
where
|
|
|
|
|
[u8; N * 2]:;
|
|
|
|
|
|
|
|
|
|
/// Returns an `impl Display` of the unsized input on the heap.
|
|
|
|
|
fn display_slice(src: &[u8]) -> DisplaySlice<'_, Self>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct Encoder<const UPPER: bool = false>;
|
|
|
|
@ -448,6 +512,31 @@ impl<const UPPER: bool> Encode for Encoder<UPPER> {
|
|
|
|
|
Vec::from_raw_parts(Box::into_raw(bytes) as *mut u8, N * 2, N * 2)
|
|
|
|
|
}) where [u8; N * 2]:);
|
|
|
|
|
impl_encode_str!(enc_str_slice(&[u8]) => enc_slice (|bytes| Vec::from(bytes)));
|
|
|
|
|
|
|
|
|
|
impl_encode_write!(write_sized<N>(&[u8; N]) => enc_sized (|bytes| &bytes) where [u8; N * 2]:);
|
|
|
|
|
impl_encode_write!(write_sized_heap<N>(&[u8; N]) => enc_sized_heap (|bytes| bytes.as_ref()) where [u8; N * 2]:);
|
|
|
|
|
impl_encode_write!(write_slice(&[u8]) => enc_slice (|bytes| bytes.as_ref()));
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn display_sized<const N: usize>(src: &[u8; N]) -> DisplaySized<'_, Self, N>
|
|
|
|
|
where
|
|
|
|
|
[u8; N * 2]:,
|
|
|
|
|
{
|
|
|
|
|
DisplaySized(src, std::marker::PhantomData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn display_sized_heap<const N: usize>(src: &[u8; N]) -> DisplaySizedHeap<'_, Self, N>
|
|
|
|
|
where
|
|
|
|
|
[u8; N * 2]:,
|
|
|
|
|
{
|
|
|
|
|
DisplaySizedHeap(src, std::marker::PhantomData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn display_slice(src: &[u8]) -> DisplaySlice<'_, Self> {
|
|
|
|
|
DisplaySlice(src, std::marker::PhantomData)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<const UPPER: bool> Encoder<UPPER> {
|
|
|
|
|