use crate::{
LEN_SIZE, Rapira, RapiraError, Result,
max_cap::{VEC_MAX_CAP, VEC_MAX_SIZE_OF},
primitive::bytes_rapira,
str_rapira,
};
#[cfg(feature = "std")]
use crate::{byte_rapira, push, try_push};
#[cfg(feature = "alloc")]
use alloc::{borrow::Cow, collections::BTreeMap};
#[cfg(feature = "std")]
use std::net::{IpAddr, Ipv6Addr, SocketAddrV6};
#[cfg(feature = "alloc")]
impl Rapira for String {
const MIN_SIZE: usize = LEN_SIZE;
#[inline]
fn size(&self) -> usize {
str_rapira::size(self)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
str_rapira::check_bytes::<()>(core::marker::PhantomData, slice)
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let s = str_rapira::from_slice(slice)?;
let s = s.to_owned();
Ok(s)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let s = unsafe { str_rapira::from_slice_unchecked(slice)? };
Ok(s.to_owned())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let s = unsafe { str_rapira::from_slice_unsafe(slice)? };
Ok(s.to_owned())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
str_rapira::convert_to_bytes(self, slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
str_rapira::try_convert_to_bytes(self, slice, cursor)
}
}
#[cfg(feature = "alloc")]
impl Rapira for Vec<u8> {
const MIN_SIZE: usize = LEN_SIZE;
#[inline]
fn size(&self) -> usize {
bytes_rapira::size(self)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
bytes_rapira::check_bytes::<()>(core::marker::PhantomData, slice)
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes = bytes_rapira::from_slice(slice)?;
Ok(bytes.to_vec())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let bytes = unsafe { bytes_rapira::from_slice_unsafe(slice)? };
Ok(bytes.to_vec())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
bytes_rapira::convert_to_bytes(self, slice, cursor);
}
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
bytes_rapira::try_convert_to_bytes(self, slice, cursor)
}
}
#[cfg(feature = "alloc")]
impl<T: Rapira> Rapira for Vec<T> {
const MIN_SIZE: usize = LEN_SIZE;
#[inline]
fn size(&self) -> usize {
match T::STATIC_SIZE {
Some(size) => 4 + (size * self.len()),
None => 4 + self.iter().fold(0, |b, v| b + v.size()),
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let len = u32::from_slice(slice)? as usize;
for _ in 0..len {
T::check_bytes(slice)?;
}
Ok(())
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let len = u32::from_slice(slice)? as usize;
if len > VEC_MAX_CAP {
return Err(RapiraError::MaxCapacity);
}
let size = core::mem::size_of::<Vec<T>>() * len;
if size > VEC_MAX_SIZE_OF {
return Err(RapiraError::MaxSize);
}
let mut vec: Vec<T> = Vec::with_capacity(len);
for _ in 0..len {
let val = T::from_slice(slice)?;
vec.push(val);
}
Ok(vec)
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let len = u32::from_slice(slice)? as usize;
if len > VEC_MAX_CAP {
return Err(RapiraError::MaxCapacity);
}
let size = core::mem::size_of::<Vec<T>>() * len;
if size > VEC_MAX_SIZE_OF {
return Err(RapiraError::MaxSize);
}
let mut vec: Vec<T> = Vec::with_capacity(len);
for _ in 0..len {
let val = T::from_slice_versioned(slice, version)?;
vec.push(val);
}
Ok(vec)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let len = u32::from_slice(slice)? as usize;
let mut vec: Vec<T> = Vec::with_capacity(len);
for _ in 0..len {
let val = unsafe { T::from_slice_unchecked(slice)? };
vec.push(val);
}
Ok(vec)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let len = unsafe { u32::from_slice_unsafe(slice)? } as usize;
let mut vec: Vec<T> = Vec::with_capacity(len);
for _ in 0..len {
let val = unsafe { T::from_slice_unsafe(slice)? };
vec.push(val);
}
Ok(vec)
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let len = self.len() as u32;
len.try_convert_to_bytes(slice, cursor)?;
for val in self.iter() {
val.try_convert_to_bytes(slice, cursor)?;
}
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let len = self.len() as u32;
len.convert_to_bytes(slice, cursor);
for val in self.iter() {
val.convert_to_bytes(slice, cursor);
}
}
}
#[cfg(feature = "alloc")]
impl<T: Rapira> Rapira for Box<T> {
const STATIC_SIZE: Option<usize> = T::STATIC_SIZE;
const MIN_SIZE: usize = T::MIN_SIZE;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let t = T::from_slice(slice)?;
Ok(Box::new(t))
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self>
where
Self: Sized,
{
let t = T::from_slice_versioned(slice, version)?;
Ok(Box::new(t))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
T::check_bytes(slice)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t = T::from_slice_unchecked(slice)?;
Ok(Box::new(t))
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let t = T::from_slice_unsafe(slice)?;
Ok(Box::new(t))
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.as_ref().try_convert_to_bytes(slice, cursor)
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.as_ref().convert_to_bytes(slice, cursor)
}
#[inline]
fn size(&self) -> usize {
self.as_ref().size()
}
}
#[cfg(feature = "alloc")]
impl<K: Rapira, V: Rapira> Rapira for BTreeMap<K, V>
where
K: Ord,
{
const MIN_SIZE: usize = LEN_SIZE;
#[inline]
fn size(&self) -> usize {
if let Some(k) = K::STATIC_SIZE {
if let Some(v) = V::STATIC_SIZE {
4 + (self.len() * (k + v))
} else {
4 + (k * self.len()) + self.iter().fold(0, |b, (_, v)| b + v.size())
}
} else {
4 + self.iter().fold(0, |b, (k, v)| {
b + k.size() + V::STATIC_SIZE.unwrap_or_else(|| v.size())
})
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let len = u32::from_slice(slice)? as usize;
for _ in 0..len {
K::check_bytes(slice)?;
V::check_bytes(slice)?;
}
Ok(())
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self> {
let len = u32::from_slice(slice)? as usize;
let mut map = BTreeMap::<K, V>::new();
for _ in 0..len {
let key = K::from_slice(slice)?;
let value = V::from_slice(slice)?;
map.insert(key, value);
}
Ok(map)
}
#[inline]
fn from_slice_versioned(slice: &mut &[u8], version: u8) -> Result<Self> {
let len = u32::from_slice(slice)? as usize;
let mut map = BTreeMap::<K, V>::new();
for _ in 0..len {
let key = K::from_slice_versioned(slice, version)?;
let value = V::from_slice_versioned(slice, version)?;
map.insert(key, value);
}
Ok(map)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self> {
let len = u32::from_slice(slice)? as usize;
let mut map = BTreeMap::<K, V>::new();
for _ in 0..len {
let key = unsafe { K::from_slice_unchecked(slice)? };
let value = unsafe { V::from_slice_unchecked(slice)? };
map.insert(key, value);
}
Ok(map)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let len = u32::from_slice_unsafe(slice)?;
let mut map = BTreeMap::<K, V>::new();
for _ in 0..len {
let key = K::from_slice_unsafe(slice)?;
let value = V::from_slice_unsafe(slice)?;
map.insert(key, value);
}
Ok(map)
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
let len = self.len() as u32;
len.try_convert_to_bytes(slice, cursor)?;
for (key, value) in self {
key.try_convert_to_bytes(slice, cursor)?;
value.try_convert_to_bytes(slice, cursor)?;
}
Ok(())
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
let len = self.len() as u32;
len.convert_to_bytes(slice, cursor);
for (key, value) in self {
key.convert_to_bytes(slice, cursor);
value.convert_to_bytes(slice, cursor);
}
}
}
#[cfg(feature = "alloc")]
impl Rapira for Cow<'_, str> {
const MIN_SIZE: usize = LEN_SIZE;
#[inline]
fn size(&self) -> usize {
str_rapira::size(self)
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
str_rapira::check_bytes::<()>(core::marker::PhantomData, slice)
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let s = str_rapira::from_slice(slice)?;
let s = Cow::Owned(s.to_owned());
Ok(s)
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let s = unsafe { str_rapira::from_slice_unchecked(slice)? };
let s = Cow::Owned(s.to_owned());
Ok(s)
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let s = str_rapira::from_slice_unsafe(slice)?;
let s = Cow::Owned(s.to_owned());
Ok(s)
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
str_rapira::convert_to_bytes(self, slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
str_rapira::try_convert_to_bytes(self, slice, cursor)
}
}
#[cfg(feature = "std")]
impl Rapira for IpAddr {
const MIN_SIZE: usize = 1 + 4;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b == 0 {
let v4 = <[u8; 4]>::from_slice(slice)?;
Ok(IpAddr::from(v4))
} else {
let v6 = Ipv6Addr::from_slice(slice)?;
Ok(IpAddr::from(v6))
}
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
let b = byte_rapira::from_slice(slice)?;
if b == 0 {
<[u8; 4]>::check_bytes(slice)?;
} else {
Ipv6Addr::check_bytes(slice)?;
}
Ok(())
}
#[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 v4 = <[u8; 4]>::from_slice_unsafe(slice)?;
Ok(IpAddr::from(v4))
} else {
let v6 = Ipv6Addr::from_slice_unsafe(slice)?;
Ok(IpAddr::from(v6))
}
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
match self {
IpAddr::V4(v4) => {
push(slice, cursor, 0);
v4.octets().convert_to_bytes(slice, cursor);
}
IpAddr::V6(v6) => {
push(slice, cursor, 1);
v6.convert_to_bytes(slice, cursor);
}
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
match self {
IpAddr::V4(v4) => {
try_push(slice, cursor, 0)?;
v4.octets().try_convert_to_bytes(slice, cursor)?;
}
IpAddr::V6(v6) => {
try_push(slice, cursor, 1)?;
v6.try_convert_to_bytes(slice, cursor)?;
}
}
Ok(())
}
#[inline]
fn size(&self) -> usize {
1 + match self {
IpAddr::V4(_) => 4,
IpAddr::V6(_) => 16,
}
}
}
#[cfg(feature = "std")]
impl Rapira for Ipv6Addr {
const STATIC_SIZE: Option<usize> = Some(16);
const MIN_SIZE: usize = 16;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let v6 = <[u8; 16]>::from_slice(slice)?;
Ok(Ipv6Addr::from(v6))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
<[u8; 16]>::check_bytes(slice)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let v6 = <[u8; 16]>::from_slice_unsafe(slice)?;
Ok(Ipv6Addr::from(v6))
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.octets().convert_to_bytes(slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.octets().try_convert_to_bytes(slice, cursor)
}
#[inline]
fn size(&self) -> usize {
16
}
}
#[cfg(feature = "std")]
impl Rapira for SocketAddrV6 {
const STATIC_SIZE: Option<usize> = Some(16 + 2);
const MIN_SIZE: usize = 16 + 2;
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
let ip = Ipv6Addr::from_slice(slice)?;
let port = u16::from_slice(slice)?;
Ok(SocketAddrV6::new(ip, port, 0, 0))
}
#[inline]
fn check_bytes(slice: &mut &[u8]) -> Result<()>
where
Self: Sized,
{
Ipv6Addr::check_bytes(slice)?;
u16::check_bytes(slice)?;
Ok(())
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let ip = Ipv6Addr::from_slice_unsafe(slice)?;
let port = u16::from_slice_unsafe(slice)?;
Ok(SocketAddrV6::new(ip, port, 0, 0))
}
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
self.ip().convert_to_bytes(slice, cursor);
self.port().convert_to_bytes(slice, cursor);
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
self.ip().try_convert_to_bytes(slice, cursor)?;
self.port().try_convert_to_bytes(slice, cursor)?;
Ok(())
}
#[inline]
fn size(&self) -> usize {
16 + 2
}
}