#[cfg(feature = "schema")]
use crate::schema::ShapeRel;
use crate::{
LEN_SIZE, Rapira, RapiraError, RapiraFlags, Result, bytes_rapira,
max_cap::{VEC_MAX_CAP, VEC_MAX_SIZE_OF},
str_rapira,
};
#[cfg(feature = "schema")]
use crate::{PeerRead, schema::shape_compat};
#[cfg(feature = "schema")]
use armour_typ::scalar::ScalarTyp;
#[cfg(feature = "schema")]
use armour_typ::{SchemaFields, SchemaTyp};
#[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")]
#[cfg(feature = "schema")]
impl PeerRead for Vec<u8> {
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
match peer {
SchemaTyp::Scalar(ScalarTyp::Bytes) => Self::from_slice_ctx(slice, flags),
_ => Err(RapiraError::SchemaMismatch),
}
}
}
#[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<()> {
bytes_rapira::check_bytes::<()>(core::marker::PhantomData, slice)
}
#[inline]
fn from_slice(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
Ok(bytes_rapira::from_slice(slice)?.to_owned())
}
#[inline]
unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes = bytes_rapira::from_slice_unchecked(slice)?;
Ok(bytes.to_owned())
}
}
#[inline]
unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
where
Self: Sized,
{
unsafe {
let bytes = bytes_rapira::from_slice_unsafe(slice)?;
Ok(bytes.to_owned())
}
}
#[inline]
fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
bytes_rapira::try_convert_to_bytes(self, slice, cursor)
}
#[inline]
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
bytes_rapira::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 size_ctx(&self, flags: RapiraFlags) -> usize {
match T::STATIC_SIZE {
Some(size) => 4 + (size * self.len()),
None => 4 + self.iter().fold(0, |b, v| b + v.size_ctx(flags)),
}
}
#[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::<T>()
.checked_mul(len)
.ok_or(RapiraError::MaxSize)?;
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_ctx(slice: &mut &[u8], flags: RapiraFlags) -> 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::<T>()
.checked_mul(len)
.ok_or(RapiraError::MaxSize)?;
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_ctx(slice, flags)?;
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::<T>()
.checked_mul(len)
.ok_or(RapiraError::MaxSize)?;
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);
}
}
#[inline]
fn convert_to_bytes_ctx(&self, slice: &mut [u8], cursor: &mut usize, flags: RapiraFlags) {
let len = self.len() as u32;
len.convert_to_bytes(slice, cursor);
for val in self.iter() {
val.convert_to_bytes_ctx(slice, cursor, flags);
}
}
}
#[cfg(feature = "schema")]
#[cfg(feature = "alloc")]
impl<T: PeerRead> PeerRead for Vec<T> {
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
let SchemaTyp::Vec(inner) = peer else {
return Err(RapiraError::SchemaMismatch);
};
match shape_compat(&T::TYPE, inner) {
ShapeRel::Exact => Self::from_slice_ctx(slice, flags),
ShapeRel::Compatible => {
let len = u32::from_slice(slice)? as usize;
if len > VEC_MAX_CAP {
return Err(RapiraError::MaxCapacity);
}
let size = core::mem::size_of::<T>()
.checked_mul(len)
.ok_or(RapiraError::MaxSize)?;
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_with_peer_ctx(slice, inner, flags)?;
vec.push(val);
}
Ok(vec)
}
_ => Err(RapiraError::SchemaMismatch),
}
}
}
#[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 from_slice_ctx(slice: &mut &[u8], flags: RapiraFlags) -> Result<Self>
where
Self: Sized,
{
let t = T::from_slice_ctx(slice, flags)?;
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 size_ctx(&self, flags: RapiraFlags) -> usize {
self.as_ref().size_ctx(flags)
}
#[inline]
fn convert_to_bytes_ctx(&self, slice: &mut [u8], cursor: &mut usize, flags: RapiraFlags) {
self.as_ref().convert_to_bytes_ctx(slice, cursor, flags)
}
#[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 = "schema")]
#[cfg(feature = "alloc")]
impl<T: PeerRead> PeerRead for Box<T> {
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
let value = T::from_slice_with_peer_ctx(slice, peer, flags)?;
Ok(Box::new(value))
}
}
#[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 size_ctx(&self, flags: RapiraFlags) -> usize {
4 + self
.iter()
.fold(0, |b, (k, v)| b + k.size_ctx(flags) + v.size_ctx(flags))
}
#[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_ctx(slice: &mut &[u8], flags: RapiraFlags) -> 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_ctx(slice, flags)?;
let value = V::from_slice_ctx(slice, flags)?;
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);
}
}
#[inline]
fn convert_to_bytes_ctx(&self, slice: &mut [u8], cursor: &mut usize, flags: RapiraFlags) {
let len = self.len() as u32;
len.convert_to_bytes(slice, cursor);
for (key, value) in self {
key.convert_to_bytes_ctx(slice, cursor, flags);
value.convert_to_bytes_ctx(slice, cursor, flags);
}
}
}
#[cfg(feature = "schema")]
#[cfg(feature = "alloc")]
impl<K: PeerRead + Ord, V: PeerRead> PeerRead for BTreeMap<K, V> {
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
let SchemaTyp::Vec(inner_pair) = peer else {
return Err(RapiraError::SchemaMismatch);
};
let SchemaTyp::Struct {
fields: SchemaFields::Unnamed(pair_fields),
..
} = &**inner_pair
else {
return Err(RapiraError::SchemaMismatch);
};
if pair_fields.len() < 2 {
return Err(RapiraError::SchemaMismatch);
}
let mut tmp = *slice;
let len = u32::from_slice(&mut tmp)? as usize;
if len > VEC_MAX_CAP {
return Err(RapiraError::MaxCapacity);
}
let mut map = BTreeMap::<K, V>::new();
for _ in 0..len {
let mut key = None;
let mut value = None;
for (idx, field_peer) in pair_fields.iter().enumerate() {
match idx {
0 => key = Some(K::from_slice_with_peer_ctx(&mut tmp, field_peer, flags)?),
1 => value = Some(V::from_slice_with_peer_ctx(&mut tmp, field_peer, flags)?),
_ => crate::schema::skip_value(&mut tmp, field_peer)?,
}
}
match (key, value) {
(Some(key), Some(value)) => {
map.insert(key, value);
}
_ => return Err(RapiraError::SchemaMismatch),
}
}
*slice = tmp;
Ok(map)
}
}
#[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 = "schema")]
#[cfg(feature = "std")]
impl PeerRead for IpAddr {
#[inline]
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
match crate::schema::shape_compat(&<Self as armour_typ::GetType>::TYPE, peer) {
ShapeRel::Exact => Self::from_slice_ctx(slice, flags),
_ => Err(RapiraError::SchemaMismatch),
}
}
}
#[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 = "schema")]
#[cfg(feature = "std")]
impl PeerRead for Ipv6Addr {
#[inline]
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
match crate::schema::shape_compat(&<Self as armour_typ::GetType>::TYPE, peer) {
ShapeRel::Exact => Self::from_slice_ctx(slice, flags),
_ => Err(RapiraError::SchemaMismatch),
}
}
}
#[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
}
}
#[cfg(feature = "schema")]
#[cfg(feature = "std")]
impl PeerRead for SocketAddrV6 {
#[inline]
fn from_slice_with_peer_ctx(
slice: &mut &[u8],
peer: &SchemaTyp,
flags: RapiraFlags,
) -> Result<Self>
where
Self: Sized,
{
match crate::schema::shape_compat(&<Self as armour_typ::GetType>::TYPE, peer) {
ShapeRel::Exact => Self::from_slice_ctx(slice, flags),
_ => Err(RapiraError::SchemaMismatch),
}
}
}