use core::{
mem::{MaybeUninit, size_of, transmute_copy},
num::{NonZeroU32, NonZeroU64},
time::Duration,
};
use crate::{Rapira, RapiraError, Result, enum_min_size, enum_size, push, static_size, try_push};
impl Rapira for () {
const STATIC_SIZE: Option<usize> = Some(0);
const MIN_SIZE: usize = 0;
#[inline]
fn check_bytes(_: &mut &[u8]) -> Result<()> {
Ok(())
}
#[inline]
fn from_slice(_: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(_: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
Ok(())
}
#[inline]
fn convert_to_bytes(&self, _: &mut [u8], _: &mut usize) {}
#[inline]
fn size(&self) -> usize {
0
}
}
impl Rapira for bool {
const STATIC_SIZE: Option<usize> = Some(1);
const MIN_SIZE: usize = 1;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let byte = *slice.first().ok_or(RapiraError::SliceLen)?;
*slice = &slice[1..];
Ok(byte != 0)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
*slice = slice.get(1..).ok_or(RapiraError::SliceLen)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let byte = *slice.get_unchecked(0);
*slice = slice.get_unchecked(1..);
Ok(byte != 0)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
slice[*cursor] = u8::from(*self);
*cursor += 1;
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let byte = slice.get_mut(*cursor).ok_or(RapiraError::SliceLen)?;
*byte = u8::from(*self);
*cursor += 1;
Ok(())
}
#[inline]
fn size(&self) -> usize {
1
}
}
pub mod byte_rapira {
use core::marker::PhantomData;
use super::*;
pub const fn static_size<T>(_: PhantomData<T>) -> Option<usize> {
Some(1)
}
pub const fn min_size<T>(_: PhantomData<T>) -> usize {
1
}
#[inline]
pub fn size(_: &u8) -> usize {
1
}
#[inline]
pub fn check_bytes<T>(_: PhantomData<T>, slice: &mut &[u8]) -> Result<()> {
*slice = slice.get(1..).ok_or(RapiraError::SliceLen)?;
Ok(())
}
#[inline]
pub fn from_slice(slice: &mut &[u8]) -> Result<u8> {
let byte = *slice.first().ok_or(RapiraError::SliceLen)?;
*slice = &slice[1..];
Ok(byte)
}
#[inline]
pub unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<u8> {
from_slice(slice)
}
#[inline]
pub unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<u8> {
unsafe {
let byte = *slice.get_unchecked(0);
*slice = slice.get_unchecked(1..);
Ok(byte)
}
}
#[inline]
pub fn convert_to_bytes(item: &u8, slice: &mut [u8], cursor: &mut usize) {
slice[*cursor] = *item;
*cursor += 1;
}
#[inline]
pub fn try_convert_to_bytes(item: &u8, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let byte = slice.get_mut(*cursor).ok_or(RapiraError::SliceLen)?;
*byte = *item;
*cursor += 1;
Ok(())
}
}
#[inline(always)]
pub fn into_arr<const N: usize>(slice: &[u8]) -> Result<[u8; N], RapiraError> {
let slice: &[u8; N] = slice.first_chunk().ok_or(RapiraError::SliceLen)?;
Ok(*slice)
}
macro_rules! impl_for_integer {
($type: ident) => {
impl Rapira for $type {
const STATIC_SIZE: Option<usize> = Some(size_of::<$type>());
const MIN_SIZE: usize = size_of::<$type>();
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; size_of::<$type>()] = into_arr(slice)?;
let u = <$type>::from_le_bytes(bytes);
*slice = &slice[size_of::<$type>()..];
Ok(u)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
*slice = slice
.get(size_of::<$type>()..)
.ok_or(RapiraError::SliceLen)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes: &[u8] = slice.get_unchecked(..size_of::<$type>());
let arr: &[u8; size_of::<$type>()] = transmute_copy(&bytes);
let u = <$type>::from_le_bytes(*arr);
*slice = slice.get_unchecked(size_of::<$type>()..);
Ok(u)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let bytes = self.to_le_bytes();
let end = *cursor + size_of::<$type>();
let s = &mut slice[*cursor..end];
s.copy_from_slice(&bytes);
*cursor = end;
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let bytes = self.to_le_bytes();
let end = *cursor + size_of::<$type>();
let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
s.copy_from_slice(&bytes);
*cursor = end;
Ok(())
}
#[inline]
fn size(&self) -> usize {
size_of::<$type>()
}
}
};
}
impl_for_integer!(i8);
impl_for_integer!(i16);
impl_for_integer!(i32);
impl_for_integer!(i64);
impl_for_integer!(i128);
impl_for_integer!(u16);
impl_for_integer!(u32);
impl_for_integer!(u64);
impl_for_integer!(u128);
impl Rapira for usize {
const STATIC_SIZE: Option<usize> = Some(size_of::<u32>());
const MIN_SIZE: usize = size_of::<u32>();
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
u32::from_slice(slice).map(|u| u as usize)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
u32::check_bytes(slice)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe { u32::from_slice_unsafe(slice).map(|u| u as usize) }
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
(*self as u32).convert_to_bytes(slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let bytes = (*self as u32).to_le_bytes();
let end = *cursor + size_of::<u32>();
let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
s.copy_from_slice(&bytes);
*cursor = end;
Ok(())
}
#[inline]
fn size(&self) -> usize {
size_of::<u32>()
}
}
impl Rapira for isize {
const STATIC_SIZE: Option<usize> = Some(size_of::<i64>());
const MIN_SIZE: usize = size_of::<i64>();
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
i64::from_slice(slice).map(|u| u as isize)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
i64::check_bytes(slice)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe { i64::from_slice_unsafe(slice).map(|u| u as isize) }
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
(*self as i64).convert_to_bytes(slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let bytes = (*self as i64).to_le_bytes();
let end = *cursor + size_of::<i64>();
let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
s.copy_from_slice(&bytes);
*cursor = end;
Ok(())
}
#[inline]
fn size(&self) -> usize {
size_of::<i64>()
}
}
impl Rapira for NonZeroU32 {
const STATIC_SIZE: Option<usize> = Some(size_of::<Self>());
const MIN_SIZE: usize = size_of::<Self>();
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let bytes = slice
.get(..size_of::<Self>())
.ok_or(RapiraError::SliceLen)?;
if bytes == [0u8; size_of::<Self>()] {
Err(RapiraError::NonZero)
} else {
*slice = &slice[size_of::<Self>()..];
Ok(())
}
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let u = u32::from_slice(slice)?;
let u = NonZeroU32::new(u).ok_or(RapiraError::NonZero)?;
Ok(u)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let u = u32::from_slice(slice)?;
let u = unsafe { NonZeroU32::new_unchecked(u) };
Ok(u)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let u = u32::from_slice_unsafe(slice)?;
let u = NonZeroU32::new_unchecked(u);
Ok(u)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let bytes = self.get();
bytes.convert_to_bytes(slice, cursor);
}
#[inline]
fn size(&self) -> usize {
size_of::<Self>()
}
}
impl Rapira for NonZeroU64 {
const STATIC_SIZE: Option<usize> = Some(size_of::<Self>());
const MIN_SIZE: usize = size_of::<Self>();
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let bytes = slice
.get(..size_of::<Self>())
.ok_or(RapiraError::SliceLen)?;
if bytes == [0u8; size_of::<Self>()] {
Err(RapiraError::NonZero)
} else {
*slice = &slice[size_of::<Self>()..];
Ok(())
}
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let u = u64::from_slice(slice)?;
let u = NonZeroU64::new(u).ok_or(RapiraError::NonZero)?;
Ok(u)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let u = u64::from_slice(slice)?;
let u = unsafe { NonZeroU64::new_unchecked(u) };
Ok(u)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let u = u64::from_slice_unsafe(slice)?;
let u = NonZeroU64::new_unchecked(u);
Ok(u)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let bytes = self.get();
bytes.convert_to_bytes(slice, cursor);
}
#[inline]
fn size(&self) -> usize {
size_of::<Self>()
}
}
impl Rapira for f32 {
const STATIC_SIZE: Option<usize> = Some(size_of::<Self>());
const MIN_SIZE: usize = size_of::<Self>();
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = f32::from_le_bytes(bytes);
if !u.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
*slice = &slice[size_of::<Self>()..];
Ok(u)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = f32::from_le_bytes(bytes);
*slice = unsafe { slice.get_unchecked(size_of::<Self>()..) };
Ok(u)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = Self::from_le_bytes(bytes);
if !u.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
*slice = &slice[size_of::<Self>()..];
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes: &[u8] = slice.get_unchecked(..size_of::<Self>());
let arr: &[u8; size_of::<Self>()] = transmute_copy(&bytes);
let u = f32::from_le_bytes(*arr);
*slice = slice.get_unchecked(size_of::<Self>()..);
Ok(u)
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
if !self.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
self.convert_to_bytes(slice, cursor);
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
assert!(self.is_finite(), "f32 is not finite");
let bytes = self.to_le_bytes();
let end = *cursor + size_of::<Self>();
slice[*cursor..end].copy_from_slice(&bytes);
*cursor = end;
}
#[inline]
fn size(&self) -> usize {
4
}
}
impl Rapira for f64 {
const STATIC_SIZE: Option<usize> = Some(size_of::<Self>());
const MIN_SIZE: usize = size_of::<Self>();
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = f64::from_le_bytes(bytes);
if !u.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
*slice = &slice[size_of::<Self>()..];
Ok(u)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = f64::from_le_bytes(bytes);
*slice = unsafe { slice.get_unchecked(size_of::<Self>()..) };
Ok(u)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let bytes: [u8; size_of::<Self>()] = into_arr(slice)?;
let u = Self::from_le_bytes(bytes);
if !u.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
*slice = &slice[size_of::<Self>()..];
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes: &[u8] = slice.get_unchecked(..size_of::<Self>());
let arr: &[u8; size_of::<Self>()] = transmute_copy(&bytes);
let u = f64::from_le_bytes(*arr);
*slice = slice.get_unchecked(size_of::<Self>()..);
Ok(u)
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
if !self.is_finite() {
return Err(RapiraError::FloatIsNaN);
}
self.convert_to_bytes(slice, cursor);
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
assert!(self.is_finite(), "f64 is not finite");
let bytes = self.to_le_bytes();
let end = *cursor + size_of::<Self>();
slice[*cursor..end].copy_from_slice(&bytes);
*cursor = end;
}
#[inline]
fn size(&self) -> usize {
8
}
}
impl<T: Rapira> Rapira for Option<T> {
const STATIC_SIZE: Option<usize> = None;
const MIN_SIZE: usize = T::MIN_SIZE + 1;
#[inline]
fn size(&self) -> usize {
match self {
None => 1,
Some(t) => 1 + t.size(),
}
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b != 0 {
let t = T::from_slice(slice)?;
Ok(Some(t))
} else {
Ok(None)
}
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b != 0 {
let t = T::from_slice_versioned(slice, version)?;
Ok(Some(t))
} else {
Ok(None)
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b != 0 {
T::check_bytes(slice)?;
}
Ok(())
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b != 0 {
let t = unsafe { T::from_slice_unchecked(slice)? };
Ok(Some(t))
} else {
Ok(None)
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let b = byte_rapira::from_slice_unsafe(slice)?;
if b != 0 {
let t = T::from_slice_unsafe(slice)?;
Ok(Some(t))
} else {
Ok(None)
}
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
match self.as_ref() {
Some(s) => {
try_push(slice, cursor, 1)?;
s.try_convert_to_bytes(slice, cursor)?;
}
None => {
try_push(slice, cursor, 0)?;
}
}
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
match self.as_ref() {
Some(s) => {
push(slice, cursor, 1);
s.convert_to_bytes(slice, cursor);
}
None => {
push(slice, cursor, 0);
}
}
}
}
impl<T: Rapira, E: Rapira> Rapira for Result<T, E> {
const STATIC_SIZE: Option<usize> = enum_size([T::STATIC_SIZE, E::STATIC_SIZE]);
const MIN_SIZE: usize = enum_min_size(&[T::MIN_SIZE, E::MIN_SIZE]);
#[inline]
fn size(&self) -> usize {
match self {
Ok(t) => 1 + t.size(),
Err(e) => 1 + e.size(),
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let discriminant = byte_rapira::from_slice(slice)?;
match discriminant {
0 => T::check_bytes(slice),
1 => E::check_bytes(slice),
_ => Err(RapiraError::EnumVariant),
}
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let discriminant = byte_rapira::from_slice(slice)?;
match discriminant {
0 => Ok(Ok(T::from_slice(slice)?)),
1 => Ok(Err(E::from_slice(slice)?)),
_ => Err(RapiraError::EnumVariant),
}
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let discriminant = byte_rapira::from_slice(slice)?;
match discriminant {
0 => Ok(Ok(T::from_slice_versioned(slice, version)?)),
1 => Ok(Err(E::from_slice_versioned(slice, version)?)),
_ => Err(RapiraError::EnumVariant),
}
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let discriminant = byte_rapira::from_slice_unchecked(slice)?;
match discriminant {
0 => Ok(Ok(T::from_slice_unchecked(slice)?)),
1 => Ok(Err(E::from_slice_unchecked(slice)?)),
_ => Err(RapiraError::EnumVariant),
}
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let b = byte_rapira::from_slice_unsafe(slice)?;
if b == 0 {
let t = T::from_slice_unsafe(slice)?;
Ok(Ok(t))
} else {
let e = E::from_slice_unsafe(slice)?;
Ok(Err(e))
}
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
match self.as_ref() {
Ok(s) => {
try_push(slice, cursor, 0)?;
s.try_convert_to_bytes(slice, cursor)?;
}
Err(e) => {
try_push(slice, cursor, 1)?;
e.try_convert_to_bytes(slice, cursor)?;
}
}
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
match self.as_ref() {
Ok(s) => {
push(slice, cursor, 0);
s.convert_to_bytes(slice, cursor);
}
Err(e) => {
push(slice, cursor, 1);
e.convert_to_bytes(slice, cursor);
}
}
}
}
#[cfg(feature = "either")]
impl<L: Rapira, R: Rapira> Rapira for either::Either<L, R> {
const STATIC_SIZE: Option<usize> = enum_size([L::STATIC_SIZE, R::STATIC_SIZE]);
const MIN_SIZE: usize = enum_min_size(&[L::MIN_SIZE, R::MIN_SIZE]);
#[inline]
fn size(&self) -> usize {
1 + match self {
either::Either::Left(l) => l.size(),
either::Either::Right(r) => r.size(),
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()> {
let discriminant = byte_rapira::from_slice(slice)?;
match discriminant {
0 => L::check_bytes(slice),
1 => R::check_bytes(slice),
_ => Err(RapiraError::EnumVariant),
}
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self> {
let discriminant = byte_rapira::from_slice(slice)?;
match discriminant {
0 => Ok(either::Either::Left(L::from_slice(slice)?)),
1 => Ok(either::Either::Right(R::from_slice(slice)?)),
_ => Err(RapiraError::EnumVariant),
}
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let discriminant = byte_rapira::from_slice_unchecked(slice)?;
match discriminant {
0 => Ok(either::Either::Left(L::from_slice_unchecked(slice)?)),
1 => Ok(either::Either::Right(R::from_slice_unchecked(slice)?)),
_ => Err(RapiraError::EnumVariant),
}
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self> {
unsafe {
let discriminant = byte_rapira::from_slice_unsafe(slice)?;
match discriminant {
0 => Ok(either::Either::Left(L::from_slice_unsafe(slice)?)),
1 => Ok(either::Either::Right(R::from_slice_unsafe(slice)?)),
_ => Err(RapiraError::EnumVariant),
}
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
match self {
either::Either::Left(l) => {
try_push(slice, cursor, 0)?;
l.try_convert_to_bytes(slice, cursor)?;
}
either::Either::Right(r) => {
try_push(slice, cursor, 1)?;
r.try_convert_to_bytes(slice, cursor)?;
}
}
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
match self {
either::Either::Left(l) => {
push(slice, cursor, 0);
l.convert_to_bytes(slice, cursor);
}
either::Either::Right(r) => {
push(slice, cursor, 1);
r.convert_to_bytes(slice, cursor);
}
}
}
}
impl<const CAP: usize> Rapira for [u8; CAP] {
const STATIC_SIZE: Option<usize> = Some(CAP);
const MIN_SIZE: usize = CAP;
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
*slice = slice.get(CAP..).ok_or(RapiraError::SliceLen)?;
Ok(())
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes: [u8; CAP] = into_arr(slice)?;
*slice = unsafe { slice.get_unchecked(CAP..) };
Ok(bytes)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes: &[u8] = slice.get_unchecked(..CAP);
let arr: &[u8; CAP] = transmute_copy(&bytes);
*slice = slice.get_unchecked(CAP..);
Ok(*arr)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let end = *cursor + CAP;
slice[*cursor..end].copy_from_slice(self);
*cursor = end;
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let end = *cursor + CAP;
let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
s.copy_from_slice(self);
*cursor = end;
Ok(())
}
#[inline]
fn size(&self) -> usize {
CAP
}
}
impl<T, const CAP: usize> Rapira for [T; CAP]
where
T: Rapira + Sized,
{
const STATIC_SIZE: Option<usize> = static_size([T::STATIC_SIZE; CAP]);
const MIN_SIZE: usize = CAP * T::MIN_SIZE;
#[inline]
fn size(&self) -> usize {
match T::STATIC_SIZE {
Some(size) => size * CAP,
None => self.iter().map(|i| i.size()).sum(),
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()> {
for _ in 0..CAP {
T::check_bytes(slice)?;
}
Ok(())
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let mut arr: [MaybeUninit<T>; CAP] = unsafe { MaybeUninit::uninit().assume_init() };
for i in 0..CAP {
match T::from_slice(slice) {
Ok(val) => {
arr.get_mut(i).ok_or(RapiraError::SliceLen)?.write(val);
}
Err(err) => {
if i != 0 {
let s = arr.get_mut(0..i).ok_or(RapiraError::SliceLen)?;
for item in s {
unsafe {
item.assume_init_drop();
}
}
}
return Err(err);
}
}
}
let arr: [T; CAP] = arr.map(|i| unsafe { i.assume_init() });
Ok(arr)
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let mut arr: [MaybeUninit<T>; CAP] = unsafe { MaybeUninit::uninit().assume_init() };
for i in 0..CAP {
match T::from_slice_versioned(slice, version) {
Ok(val) => {
arr.get_mut(i).ok_or(RapiraError::SliceLen)?.write(val);
}
Err(err) => {
if i != 0 {
let s = arr.get_mut(0..i).ok_or(RapiraError::SliceLen)?;
for item in s {
unsafe {
item.assume_init_drop();
}
}
}
return Err(err);
}
}
}
let arr: [T; CAP] = arr.map(|i| unsafe { i.assume_init() });
Ok(arr)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let mut arr: [MaybeUninit<T>; CAP] = MaybeUninit::uninit().assume_init();
for i in 0..CAP {
match T::from_slice_unchecked(slice) {
Ok(val) => {
arr.get_unchecked_mut(i).write(val);
}
Err(err) => {
if i != 0 {
for item in arr.get_unchecked_mut(0..i) {
item.assume_init_drop();
}
}
return Err(err);
}
}
}
let arr: [T; CAP] = arr.map(|i| i.assume_init());
Ok(arr)
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let mut arr: [MaybeUninit<T>; CAP] = MaybeUninit::uninit().assume_init();
for i in 0..CAP {
match T::from_slice_unsafe(slice) {
Ok(val) => {
arr.get_unchecked_mut(i).write(val);
}
Err(err) => {
if i != 0 {
for item in arr.get_unchecked_mut(0..i) {
item.assume_init_drop();
}
}
return Err(err);
}
}
}
let arr: [T; CAP] = arr.map(|i| i.assume_init());
Ok(arr)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
for val in self.iter() {
val.convert_to_bytes(slice, cursor);
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
for val in self.iter() {
val.try_convert_to_bytes(slice, cursor)?;
}
Ok(())
}
}
impl<T0: Rapira, T1: Rapira> Rapira for (T0, T1) {
const STATIC_SIZE: Option<usize> = static_size([T0::STATIC_SIZE, T1::STATIC_SIZE]);
const MIN_SIZE: usize = T0::MIN_SIZE + T1::MIN_SIZE;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice(slice)?;
let t1 = T1::from_slice(slice)?;
Ok((t0, t1))
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice_versioned(slice, version)?;
let t1 = T1::from_slice_versioned(slice, version)?;
Ok((t0, t1))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
T0::check_bytes(slice)?;
T1::check_bytes(slice)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unchecked(slice)?;
let t1 = T1::from_slice_unchecked(slice)?;
Ok((t0, t1))
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unsafe(slice)?;
let t1 = T1::from_slice_unsafe(slice)?;
Ok((t0, t1))
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.0.try_convert_to_bytes(slice, cursor)?;
self.1.try_convert_to_bytes(slice, cursor)?;
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.0.convert_to_bytes(slice, cursor);
self.1.convert_to_bytes(slice, cursor);
}
#[inline]
fn size(&self) -> usize {
let a = match T0::STATIC_SIZE {
Some(s) => s,
None => self.0.size(),
};
let b = match T1::STATIC_SIZE {
Some(s) => s,
None => self.1.size(),
};
a + b
}
}
impl<T0: Rapira, T1: Rapira, T2: Rapira> Rapira for (T0, T1, T2) {
const STATIC_SIZE: Option<usize> =
static_size([T0::STATIC_SIZE, T1::STATIC_SIZE, T2::STATIC_SIZE]);
const MIN_SIZE: usize = T0::MIN_SIZE + T1::MIN_SIZE + T2::MIN_SIZE;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice(slice)?;
let t1 = T1::from_slice(slice)?;
let t2 = T2::from_slice(slice)?;
Ok((t0, t1, t2))
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice_versioned(slice, version)?;
let t1 = T1::from_slice_versioned(slice, version)?;
let t2 = T2::from_slice_versioned(slice, version)?;
Ok((t0, t1, t2))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
T0::check_bytes(slice)?;
T1::check_bytes(slice)?;
T2::check_bytes(slice)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unchecked(slice)?;
let t1 = T1::from_slice_unchecked(slice)?;
let t2 = T2::from_slice_unchecked(slice)?;
Ok((t0, t1, t2))
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unsafe(slice)?;
let t1 = T1::from_slice_unsafe(slice)?;
let t2 = T2::from_slice_unsafe(slice)?;
Ok((t0, t1, t2))
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.0.try_convert_to_bytes(slice, cursor)?;
self.1.try_convert_to_bytes(slice, cursor)?;
self.2.try_convert_to_bytes(slice, cursor)?;
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.0.convert_to_bytes(slice, cursor);
self.1.convert_to_bytes(slice, cursor);
self.2.convert_to_bytes(slice, cursor);
}
#[inline]
fn size(&self) -> usize {
(match T0::STATIC_SIZE {
Some(s) => s,
None => self.0.size(),
}) + (match T1::STATIC_SIZE {
Some(s) => s,
None => self.1.size(),
}) + (match T2::STATIC_SIZE {
Some(s) => s,
None => self.2.size(),
})
}
}
impl<T0: Rapira, T1: Rapira, T2: Rapira, T3: Rapira> Rapira for (T0, T1, T2, T3) {
const STATIC_SIZE: Option<usize> = static_size([
T0::STATIC_SIZE,
T1::STATIC_SIZE,
T2::STATIC_SIZE,
T3::STATIC_SIZE,
]);
const MIN_SIZE: usize = T0::MIN_SIZE + T1::MIN_SIZE + T2::MIN_SIZE + T3::MIN_SIZE;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice(slice)?;
let t1 = T1::from_slice(slice)?;
let t2 = T2::from_slice(slice)?;
let t3 = T3::from_slice(slice)?;
Ok((t0, t1, t2, t3))
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let t0 = T0::from_slice_versioned(slice, version)?;
let t1 = T1::from_slice_versioned(slice, version)?;
let t2 = T2::from_slice_versioned(slice, version)?;
let t3 = T3::from_slice_versioned(slice, version)?;
Ok((t0, t1, t2, t3))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
T0::check_bytes(slice)?;
T1::check_bytes(slice)?;
T2::check_bytes(slice)?;
T3::check_bytes(slice)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unchecked(slice)?;
let t1 = T1::from_slice_unchecked(slice)?;
let t2 = T2::from_slice_unchecked(slice)?;
let t3 = T3::from_slice_unchecked(slice)?;
Ok((t0, t1, t2, t3))
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t0 = T0::from_slice_unsafe(slice)?;
let t1 = T1::from_slice_unsafe(slice)?;
let t2 = T2::from_slice_unsafe(slice)?;
let t3 = T3::from_slice_unsafe(slice)?;
Ok((t0, t1, t2, t3))
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.0.try_convert_to_bytes(slice, cursor)?;
self.1.try_convert_to_bytes(slice, cursor)?;
self.2.try_convert_to_bytes(slice, cursor)?;
self.3.try_convert_to_bytes(slice, cursor)?;
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.0.convert_to_bytes(slice, cursor);
self.1.convert_to_bytes(slice, cursor);
self.2.convert_to_bytes(slice, cursor);
self.3.convert_to_bytes(slice, cursor);
}
#[inline]
fn size(&self) -> usize {
(match T0::STATIC_SIZE {
Some(s) => s,
None => self.0.size(),
}) + (match T1::STATIC_SIZE {
Some(s) => s,
None => self.1.size(),
}) + (match T2::STATIC_SIZE {
Some(s) => s,
None => self.2.size(),
}) + (match T3::STATIC_SIZE {
Some(s) => s,
None => self.3.size(),
})
}
}
pub mod str_rapira {
use core::marker::PhantomData;
use simdutf8::basic::from_utf8;
use super::*;
use crate::{LEN_SIZE, extend, try_extend};
pub const fn static_size<T>(_: PhantomData<T>) -> Option<usize> {
None
}
pub const fn min_size<T>(_: PhantomData<T>) -> usize {
LEN_SIZE
}
#[inline]
pub fn size(s: &str) -> usize {
4 + s.len()
}
#[inline]
pub fn check_bytes<T>(_: PhantomData<T>, slice: &mut &[u8]) -> Result<()> {
let len = u32::from_slice(slice)? as usize;
let bytes = slice.get(..len).ok_or(RapiraError::SliceLen)?;
let _ = from_utf8(bytes).map_err(|_| RapiraError::StringType)?;
*slice = &slice[len..];
Ok(())
}
#[inline]
pub fn from_slice<'a>(slice: &mut &'a [u8]) -> Result<&'a str> {
let len = u32::from_slice(slice)? as usize;
let bytes = slice.get(..len).ok_or(RapiraError::SliceLen)?;
let s = from_utf8(bytes).map_err(|_| RapiraError::StringType)?;
*slice = &slice[len..];
Ok(s)
}
#[inline]
pub unsafe fn from_slice_unchecked<'a>(slice: &mut &'a [u8]) -> Result<&'a str> {
let len = u32::from_slice(slice)? as usize;
let bytes = slice.get(..len).ok_or(RapiraError::SliceLen)?;
let s = unsafe { core::str::from_utf8_unchecked(bytes) };
*slice = unsafe { slice.get_unchecked(len..) };
Ok(s)
}
#[inline]
pub unsafe fn from_slice_unsafe<'a>(slice: &mut &'a [u8]) -> Result<&'a str> {
unsafe {
let len = usize::from_slice_unsafe(slice)?;
let bytes = slice.get_unchecked(..len);
let s = core::str::from_utf8_unchecked(bytes);
*slice = slice.get_unchecked(len..);
Ok(s)
}
}
#[inline]
pub fn convert_to_bytes(item: &str, slice: &mut [u8], cursor: &mut usize) {
let len = item.len() as u32;
len.convert_to_bytes(slice, cursor);
extend(slice, cursor, item.as_bytes());
}
#[inline]
pub fn try_convert_to_bytes(item: &str, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let len = item.len() as u32;
len.try_convert_to_bytes(slice, cursor)?;
try_extend(slice, cursor, item.as_bytes())?;
Ok(())
}
}
pub mod bytes_rapira {
use core::marker::PhantomData;
use super::*;
use crate::{LEN_SIZE, extend, try_extend};
pub const fn static_size<T>(_: PhantomData<T>) -> Option<usize> {
None
}
pub const fn min_size<T>(_: PhantomData<T>) -> usize {
LEN_SIZE
}
#[inline]
pub fn size(s: &[u8]) -> usize {
4 + s.len()
}
#[inline]
pub fn check_bytes<T>(_: PhantomData<T>, slice: &mut &[u8]) -> Result<()> {
let len = u32::from_slice(slice)? as usize;
*slice = slice.get(len..).ok_or(RapiraError::SliceLen)?;
Ok(())
}
#[inline]
pub fn from_slice<'a>(slice: &mut &'a [u8]) -> Result<&'a [u8]> {
let len = u32::from_slice(slice)? as usize;
let bytes = slice.get(..len).ok_or(RapiraError::SliceLen)?;
*slice = &slice[len..];
Ok(bytes)
}
#[inline]
pub unsafe fn from_slice_unchecked<'a>(slice: &mut &'a [u8]) -> Result<&'a [u8]> {
from_slice(slice)
}
#[inline]
pub unsafe fn from_slice_unsafe<'a>(slice: &mut &'a [u8]) -> Result<&'a [u8]> {
unsafe {
let len = usize::from_slice_unsafe(slice)?;
let bytes = slice.get_unchecked(..len);
*slice = slice.get_unchecked(len..);
Ok(bytes)
}
}
#[inline]
pub fn convert_to_bytes(item: &[u8], slice: &mut [u8], cursor: &mut usize) {
let len = item.len() as u32;
len.convert_to_bytes(slice, cursor);
extend(slice, cursor, item);
}
#[inline]
pub fn try_convert_to_bytes(item: &[u8], slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let len = item.len() as u32;
len.try_convert_to_bytes(slice, cursor)?;
try_extend(slice, cursor, item)?;
Ok(())
}
}
impl Rapira for Duration {
const STATIC_SIZE: Option<usize> = Some(8);
const MIN_SIZE: usize = 8;
#[inline]
fn size(&self) -> usize {
8
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()> {
u64::check_bytes(slice)
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let secs = u64::from_slice(slice)?;
Ok(Duration::from_secs(secs))
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let secs = u64::from_slice_unsafe(slice)?;
Ok(Duration::from_secs(secs))
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let secs = self.as_secs();
secs.convert_to_bytes(slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let secs = self.as_secs();
secs.try_convert_to_bytes(slice, cursor)
}
}