#![cfg_attr(
feature = "serde",
doc = " [`SerializeOctets`] and [`DeserializeOctets`]"
)]
#![cfg_attr(
not(feature = "serde"),
doc = " `SerializeOctets` and `DeserializeOctets`"
)]
use super::name::ToDname;
use super::net::{Ipv4Addr, Ipv6Addr};
#[cfg(feature = "bytes")]
use bytes::{Bytes, BytesMut};
use core::cmp::Ordering;
use core::convert::TryFrom;
#[cfg(feature = "heapless")]
use core::iter::FromIterator;
use core::{borrow, fmt, hash};
#[cfg(feature = "smallvec")]
use smallvec::{Array, SmallVec};
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(feature = "std")]
use std::mem;
#[cfg(feature = "std")]
use std::vec::Vec;
pub trait OctetsExt: AsRef<[u8]> {
fn truncate(&mut self, len: usize);
}
impl<'a> OctetsExt for &'a [u8] {
fn truncate(&mut self, len: usize) {
if len < self.len() {
*self = &self[..len]
}
}
}
#[cfg(feature = "std")]
impl<'a> OctetsExt for Cow<'a, [u8]> {
fn truncate(&mut self, len: usize) {
match *self {
Cow::Borrowed(ref mut slice) => *slice = &slice[..len],
Cow::Owned(ref mut vec) => vec.truncate(len),
}
}
}
#[cfg(feature = "std")]
impl OctetsExt for Vec<u8> {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
#[cfg(feature = "bytes")]
impl OctetsExt for Bytes {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
#[cfg(feature = "smallvec")]
impl<A: Array<Item = u8>> OctetsExt for SmallVec<A> {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> OctetsExt for heapless::Vec<u8, N> {
fn truncate(&mut self, len: usize) {
self.truncate(len)
}
}
pub trait OctetsRef: AsRef<[u8]> + Copy + Sized {
type Range: AsRef<[u8]>;
fn range(self, start: usize, end: usize) -> Self::Range;
fn range_from(self, start: usize) -> Self::Range {
self.range(start, self.as_ref().len())
}
fn range_to(self, end: usize) -> Self::Range {
self.range(0, end)
}
fn range_all(self) -> Self::Range {
self.range(0, self.as_ref().len())
}
}
impl<'a, T: OctetsRef> OctetsRef for &'a T {
type Range = T::Range;
fn range(self, start: usize, end: usize) -> Self::Range {
(*self).range(start, end)
}
}
impl<'a> OctetsRef for &'a [u8] {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self[start..end]
}
}
#[cfg(feature = "std")]
impl<'a, 's> OctetsRef for &'a Cow<'s, [u8]> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self.as_ref()[start..end]
}
}
#[cfg(feature = "std")]
impl<'a> OctetsRef for &'a Vec<u8> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self[start..end]
}
}
#[cfg(feature = "bytes")]
impl<'a> OctetsRef for &'a Bytes {
type Range = Bytes;
fn range(self, start: usize, end: usize) -> Self::Range {
self.slice(start..end)
}
}
#[cfg(feature = "smallvec")]
impl<'a, A: Array<Item = u8>> OctetsRef for &'a SmallVec<A> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self.as_slice()[start..end]
}
}
#[cfg(feature = "heapless")]
impl<'a, const N: usize> OctetsRef for &'a heapless::Vec<u8, N> {
type Range = &'a [u8];
fn range(self, start: usize, end: usize) -> Self::Range {
&self[start..end]
}
}
pub trait OctetsFrom<Source>: Sized {
fn octets_from(source: Source) -> Result<Self, ShortBuf>;
}
impl<'a, Source: AsRef<[u8]> + 'a> OctetsFrom<&'a Source> for &'a [u8] {
fn octets_from(source: &'a Source) -> Result<Self, ShortBuf> {
Ok(source.as_ref())
}
}
#[cfg(feature = "std")]
impl<Source> OctetsFrom<Source> for Vec<u8>
where
Self: From<Source>,
{
fn octets_from(source: Source) -> Result<Self, ShortBuf> {
Ok(From::from(source))
}
}
#[cfg(feature = "bytes")]
impl<Source> OctetsFrom<Source> for Bytes
where
Self: From<Source>,
{
fn octets_from(source: Source) -> Result<Self, ShortBuf> {
Ok(From::from(source))
}
}
#[cfg(feature = "bytes")]
impl<Source> OctetsFrom<Source> for BytesMut
where
Self: From<Source>,
{
fn octets_from(source: Source) -> Result<Self, ShortBuf> {
Ok(From::from(source))
}
}
#[cfg(feature = "smallvec")]
impl<Source, A> OctetsFrom<Source> for SmallVec<A>
where
Source: AsRef<[u8]>,
A: Array<Item = u8>,
{
fn octets_from(source: Source) -> Result<Self, ShortBuf> {
Ok(smallvec::ToSmallVec::to_smallvec(source.as_ref()))
}
}
#[cfg(feature = "heapless")]
impl<Source, const N: usize> OctetsFrom<Source> for heapless::Vec<u8, N>
where
Source: AsRef<[u8]>,
{
fn octets_from(source: Source) -> Result<Self, ShortBuf> {
let source_ref = source.as_ref();
if source_ref.len() > N {
return Err(ShortBuf);
}
Ok(heapless::Vec::from_iter(source_ref.iter().copied()))
}
}
pub trait OctetsInto<Target> {
fn octets_into(self) -> Result<Target, ShortBuf>;
}
impl<Source, Target: OctetsFrom<Source>> OctetsInto<Target> for Source {
fn octets_into(self) -> Result<Target, ShortBuf> {
Target::octets_from(self)
}
}
pub trait OctetsBuilder: Sized {
type Octets;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf>;
fn truncate(&mut self, len: usize);
fn freeze(self) -> Self::Octets;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn append_all<F>(&mut self, op: F) -> Result<(), ShortBuf>
where
F: FnOnce(&mut Self) -> Result<(), ShortBuf>,
{
let pos = self.len();
match op(self) {
Ok(_) => Ok(()),
Err(_) => {
self.truncate(pos);
Err(ShortBuf)
}
}
}
fn append_compressed_dname<N: ToDname>(
&mut self,
name: &N,
) -> Result<(), ShortBuf> {
if let Some(slice) = name.as_flat_slice() {
self.append_slice(slice)
} else {
self.append_all(|target| {
for label in name.iter_labels() {
label.build(target)?;
}
Ok(())
})
}
}
fn u16_len_prefixed<F>(&mut self, op: F) -> Result<(), ShortBuf>
where
Self: AsMut<[u8]>,
F: FnOnce(&mut Self) -> Result<(), ShortBuf>,
{
let pos = self.len();
self.append_slice(&[0; 2])?;
match op(self) {
Ok(_) => {
let len = self.len() - pos - 2;
if len > usize::from(u16::max_value()) {
self.truncate(pos);
Err(ShortBuf)
} else {
self.as_mut()[pos..pos + 2]
.copy_from_slice(&(len as u16).to_be_bytes());
Ok(())
}
}
Err(_) => {
self.truncate(pos);
Err(ShortBuf)
}
}
}
}
impl<'a, T: OctetsBuilder<Octets = T>> OctetsBuilder for &'a mut T {
type Octets = &'a mut T;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
(*self).append_slice(slice)
}
fn truncate(&mut self, len: usize) {
(*self).truncate(len)
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
OctetsBuilder::len(*self)
}
fn is_empty(&self) -> bool {
OctetsBuilder::is_empty(*self)
}
}
#[cfg(feature = "std")]
impl OctetsBuilder for Vec<u8> {
type Octets = Self;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
self.extend_from_slice(slice);
Ok(())
}
fn truncate(&mut self, len: usize) {
Vec::truncate(self, len)
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
Vec::len(self)
}
fn is_empty(&self) -> bool {
Vec::is_empty(self)
}
}
#[cfg(feature = "std")]
impl<'a> OctetsBuilder for Cow<'a, [u8]> {
type Octets = Self;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
if let Cow::Owned(ref mut vec) = *self {
vec.extend_from_slice(slice);
} else {
let mut vec = mem::replace(self, Cow::Borrowed(b"")).into_owned();
vec.extend_from_slice(slice);
*self = Cow::Owned(vec);
}
Ok(())
}
fn truncate(&mut self, len: usize) {
match *self {
Cow::Owned(ref mut vec) => vec.truncate(len),
Cow::Borrowed(ref mut slice) => {
if len < slice.len() {
*slice = &slice[..len]
}
}
}
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
self.as_ref().len()
}
fn is_empty(&self) -> bool {
self.as_ref().is_empty()
}
}
#[cfg(feature = "bytes")]
impl OctetsBuilder for BytesMut {
type Octets = Bytes;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
self.extend_from_slice(slice);
Ok(())
}
fn truncate(&mut self, len: usize) {
BytesMut::truncate(self, len)
}
fn freeze(self) -> Self::Octets {
self.freeze()
}
fn len(&self) -> usize {
Self::len(self)
}
fn is_empty(&self) -> bool {
Self::is_empty(self)
}
}
#[cfg(feature = "smallvec")]
impl<A: Array<Item = u8>> OctetsBuilder for SmallVec<A> {
type Octets = Self;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
self.extend_from_slice(slice);
Ok(())
}
fn truncate(&mut self, len: usize) {
SmallVec::truncate(self, len)
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
Self::len(self)
}
fn is_empty(&self) -> bool {
Self::is_empty(self)
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> OctetsBuilder for heapless::Vec<u8, N> {
type Octets = Self;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
self.extend_from_slice(slice).map_err(|_| ShortBuf)
}
fn truncate(&mut self, len: usize) {
heapless::Vec::truncate(self, len)
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
self.as_slice().len()
}
fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
}
pub trait EmptyBuilder {
fn empty() -> Self;
fn with_capacity(capacity: usize) -> Self;
}
#[cfg(feature = "std")]
impl EmptyBuilder for Vec<u8> {
fn empty() -> Self {
Vec::new()
}
fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity)
}
}
#[cfg(feature = "bytes")]
impl EmptyBuilder for BytesMut {
fn empty() -> Self {
BytesMut::new()
}
fn with_capacity(capacity: usize) -> Self {
BytesMut::with_capacity(capacity)
}
}
#[cfg(feature = "smallvec")]
impl<A: Array<Item = u8>> EmptyBuilder for SmallVec<A> {
fn empty() -> Self {
SmallVec::new()
}
fn with_capacity(capacity: usize) -> Self {
SmallVec::with_capacity(capacity)
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> EmptyBuilder for heapless::Vec<u8, N> {
fn empty() -> Self {
heapless::Vec::new()
}
fn with_capacity(capacity: usize) -> Self {
debug_assert!(capacity <= N);
heapless::Vec::new()
}
}
pub trait IntoBuilder {
type Builder: OctetsBuilder;
fn into_builder(self) -> Self::Builder;
}
#[cfg(feature = "std")]
impl IntoBuilder for Vec<u8> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
#[cfg(feature = "std")]
impl<'a> IntoBuilder for &'a [u8] {
type Builder = Vec<u8>;
fn into_builder(self) -> Self::Builder {
self.into()
}
}
#[cfg(feature = "std")]
impl<'a> IntoBuilder for Cow<'a, [u8]> {
type Builder = Vec<u8>;
fn into_builder(self) -> Self::Builder {
self.into_owned()
}
}
#[cfg(feature = "bytes")]
impl IntoBuilder for Bytes {
type Builder = BytesMut;
fn into_builder(self) -> Self::Builder {
BytesMut::from(self.as_ref())
}
}
#[cfg(feature = "smallvec")]
impl<A: Array<Item = u8>> IntoBuilder for SmallVec<A> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> IntoBuilder for heapless::Vec<u8, N> {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
pub trait FromBuilder: AsRef<[u8]> + Sized {
type Builder: OctetsBuilder<Octets = Self>;
fn from_builder(builder: Self::Builder) -> Self;
}
#[cfg(feature = "std")]
impl FromBuilder for Vec<u8> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[cfg(feature = "bytes")]
impl FromBuilder for Bytes {
type Builder = BytesMut;
fn from_builder(builder: Self::Builder) -> Self {
builder.freeze()
}
}
#[cfg(feature = "smallvec")]
impl<A: Array<Item = u8>> FromBuilder for SmallVec<A> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> FromBuilder for heapless::Vec<u8, N> {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
#[cfg(feature = "serde")]
pub use self::serde::*;
#[cfg(feature = "serde")]
mod serde {
use core::fmt;
use core::marker::PhantomData;
use serde::de::Visitor;
pub trait SerializeOctets {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error>;
fn as_serialized_octets(&self) -> AsSerializedOctets<Self> {
AsSerializedOctets(self)
}
}
impl<'a> SerializeOctets for &'a [u8] {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self)
}
}
#[cfg(feature = "std")]
impl<'a> SerializeOctets for std::borrow::Cow<'a, [u8]> {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
#[cfg(feature = "std")]
impl SerializeOctets for std::vec::Vec<u8> {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
#[cfg(feature = "bytes")]
impl SerializeOctets for bytes::Bytes {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
#[cfg(feature = "smallvec")]
impl<A> SerializeOctets for smallvec::SmallVec<A>
where
A: smallvec::Array<Item = u8>,
{
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
#[cfg(feature = "heapless")]
impl<const N: usize> SerializeOctets for heapless::Vec<u8, N> {
fn serialize_octets<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
pub struct AsSerializedOctets<'a, T: ?Sized>(&'a T);
impl<'a, T: SerializeOctets> serde::Serialize for AsSerializedOctets<'a, T> {
fn serialize<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
self.0.serialize_octets(serializer)
}
}
pub trait DeserializeOctets<'de>: Sized {
type Visitor: Visitor<'de, Value = Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error>;
fn deserialize_with_visitor<
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>;
fn visitor() -> Self::Visitor;
}
impl<'de> DeserializeOctets<'de> for &'de [u8] {
type Visitor = BorrowedVisitor<Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_bytes(visitor)
}
fn visitor() -> Self::Visitor {
BorrowedVisitor::new()
}
}
#[cfg(feature = "std")]
impl<'de> DeserializeOctets<'de> for std::borrow::Cow<'de, [u8]> {
type Visitor = BorrowedVisitor<Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_bytes(visitor)
}
fn visitor() -> Self::Visitor {
BorrowedVisitor::new()
}
}
#[cfg(feature = "std")]
impl<'de> DeserializeOctets<'de> for std::vec::Vec<u8> {
type Visitor = BufVisitor<Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_byte_buf(visitor)
}
fn visitor() -> Self::Visitor {
BufVisitor::new()
}
}
#[cfg(feature = "bytes")]
impl<'de> DeserializeOctets<'de> for bytes::Bytes {
type Visitor = BufVisitor<Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_byte_buf(visitor)
}
fn visitor() -> Self::Visitor {
BufVisitor::new()
}
}
#[cfg(feature = "smallvec")]
impl<'de, A> DeserializeOctets<'de> for smallvec::SmallVec<A>
where
A: smallvec::Array<Item = u8>,
{
type Visitor = BufVisitor<Self>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_byte_buf(visitor)
}
fn visitor() -> Self::Visitor {
BufVisitor::new()
}
}
#[cfg(feature = "heapless")]
impl<'de, const N: usize> DeserializeOctets<'de> for heapless::Vec<u8, N> {
type Visitor = HeaplessVecVisitor<N>;
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
fn deserialize_with_visitor<D, V>(
deserializer: D,
visitor: V,
) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: serde::de::Visitor<'de>,
{
deserializer.deserialize_byte_buf(visitor)
}
fn visitor() -> Self::Visitor {
HeaplessVecVisitor::new()
}
}
pub struct BorrowedVisitor<T>(PhantomData<T>);
impl<T> BorrowedVisitor<T> {
fn new() -> Self {
BorrowedVisitor(PhantomData)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<T, D::Error>
where
T: From<&'de [u8]>,
{
deserializer.deserialize_bytes(self)
}
}
impl<'de, T> serde::de::Visitor<'de> for BorrowedVisitor<T>
where
T: From<&'de [u8]>,
{
type Value = T;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("an octet sequence")
}
fn visit_borrowed_bytes<E: serde::de::Error>(
self,
value: &'de [u8],
) -> Result<Self::Value, E> {
Ok(value.into())
}
}
#[cfg(feature = "std")]
pub struct BufVisitor<T>(PhantomData<T>);
#[cfg(feature = "std")]
impl<T> BufVisitor<T> {
fn new() -> Self {
BufVisitor(PhantomData)
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<T, D::Error>
where
T: From<std::vec::Vec<u8>>,
{
deserializer.deserialize_byte_buf(self)
}
}
#[cfg(feature = "std")]
impl<'de, T> serde::de::Visitor<'de> for BufVisitor<T>
where
T: From<std::vec::Vec<u8>>,
{
type Value = T;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("an octet sequence")
}
fn visit_borrowed_bytes<E: serde::de::Error>(
self,
value: &'de [u8],
) -> Result<Self::Value, E> {
Ok(std::vec::Vec::from(value).into())
}
fn visit_byte_buf<E: serde::de::Error>(
self,
value: std::vec::Vec<u8>,
) -> Result<Self::Value, E> {
Ok(value.into())
}
}
#[cfg(feature = "heapless")]
pub struct HeaplessVecVisitor<const N: usize>;
#[cfg(feature = "heapless")]
impl<const N: usize> HeaplessVecVisitor<N> {
fn new() -> Self {
Self
}
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<heapless::Vec<u8, N>, D::Error> {
deserializer.deserialize_byte_buf(self)
}
}
#[cfg(feature = "heapless")]
impl<'de, const N: usize> serde::de::Visitor<'de> for HeaplessVecVisitor<N> {
type Value = heapless::Vec<u8, N>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!(
"an octet sequence of length {} of shorter",
N
))
}
fn visit_bytes<E: serde::de::Error>(
self,
value: &[u8],
) -> Result<Self::Value, E> {
use core::iter::FromIterator;
if value.len() > N {
return Err(E::invalid_length(value.len(), &self));
}
Ok(heapless::Vec::from_iter(value.iter().copied()))
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct Parser<Ref> {
octets: Ref,
pos: usize,
len: usize,
}
impl<Ref> Parser<Ref> {
pub fn from_ref(octets: Ref) -> Self
where
Ref: AsRef<[u8]>,
{
Parser {
pos: 0,
len: octets.as_ref().len(),
octets,
}
}
pub fn octets_ref(&self) -> Ref
where
Ref: Copy,
{
self.octets
}
pub fn pos(&self) -> usize {
self.pos
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
}
impl Parser<&'static [u8]> {
pub fn from_static(slice: &'static [u8]) -> Self {
Self::from_ref(slice)
}
}
impl<Ref: AsRef<[u8]>> Parser<Ref> {
pub fn as_slice(&self) -> &[u8] {
&self.octets.as_ref()[..self.len]
}
pub fn as_slice_mut(&mut self) -> &mut [u8]
where
Ref: AsMut<[u8]>,
{
&mut self.octets.as_mut()[..self.len]
}
pub fn remaining(&self) -> usize {
self.len - self.pos
}
pub fn peek(&self, len: usize) -> Result<&[u8], ParseError> {
self.check_len(len)?;
Ok(&self.peek_all()[..len])
}
pub fn peek_all(&self) -> &[u8] {
&self.octets.as_ref()[self.pos..]
}
pub fn seek(&mut self, pos: usize) -> Result<(), ParseError> {
if pos > self.len {
Err(ParseError::ShortInput)
} else {
self.pos = pos;
Ok(())
}
}
pub fn advance(&mut self, len: usize) -> Result<(), ParseError> {
if len > self.remaining() {
Err(ParseError::ShortInput)
} else {
self.pos += len;
Ok(())
}
}
pub fn advance_to_end(&mut self) {
self.pos = self.len
}
pub fn check_len(&self, len: usize) -> Result<(), ParseError> {
if self.remaining() < len {
Err(ParseError::ShortInput)
} else {
Ok(())
}
}
}
impl<Ref: AsRef<[u8]>> Parser<Ref> {
pub fn parse_octets(
&mut self,
len: usize,
) -> Result<Ref::Range, ParseError>
where
Ref: OctetsRef,
{
let end = self.pos + len;
if end > self.len {
return Err(ParseError::ShortInput);
}
let res = self.octets.range(self.pos, end);
self.pos = end;
Ok(res)
}
pub fn parse_buf(&mut self, buf: &mut [u8]) -> Result<(), ParseError> {
let pos = self.pos;
self.advance(buf.len())?;
buf.copy_from_slice(&self.octets.as_ref()[pos..self.pos]);
Ok(())
}
pub fn parse_i8(&mut self) -> Result<i8, ParseError> {
let res = self.peek(1)?[0] as i8;
self.pos += 1;
Ok(res)
}
pub fn parse_u8(&mut self) -> Result<u8, ParseError> {
let res = self.peek(1)?[0];
self.pos += 1;
Ok(res)
}
pub fn parse_i16(&mut self) -> Result<i16, ParseError> {
let mut res = [0; 2];
self.parse_buf(&mut res)?;
Ok(i16::from_be_bytes(res))
}
pub fn parse_u16(&mut self) -> Result<u16, ParseError> {
let mut res = [0; 2];
self.parse_buf(&mut res)?;
Ok(u16::from_be_bytes(res))
}
pub fn parse_i32(&mut self) -> Result<i32, ParseError> {
let mut res = [0; 4];
self.parse_buf(&mut res)?;
Ok(i32::from_be_bytes(res))
}
pub fn parse_u32(&mut self) -> Result<u32, ParseError> {
let mut res = [0; 4];
self.parse_buf(&mut res)?;
Ok(u32::from_be_bytes(res))
}
pub fn parse_block<F, U>(
&mut self,
limit: usize,
op: F,
) -> Result<U, ParseError>
where
F: FnOnce(&mut Self) -> Result<U, ParseError>,
{
let end = self.pos + limit;
if end > self.len {
self.advance_to_end();
return Err(ParseError::ShortInput);
}
let len = self.len;
self.len = end;
let res = op(self);
self.len = len;
let res = if self.pos != end {
Err(ParseError::Form(FormError::new("trailing data in field")))
} else if let Err(ParseError::ShortInput) = res {
Err(ParseError::Form(FormError::new("short field")))
} else {
res
};
self.pos = end;
res
}
}
pub trait Parse<Ref>: Sized {
fn parse(parser: &mut Parser<Ref>) -> Result<Self, ParseError>;
fn skip(parser: &mut Parser<Ref>) -> Result<(), ParseError>;
}
impl<T: AsRef<[u8]>> Parse<T> for i8 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_i8().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(1).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for u8 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_u8().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(1).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for i16 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_i16().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(2).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for u16 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_u16().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(2).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for i32 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_i32().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(4).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for u32 {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
parser.parse_u32().map_err(Into::into)
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(4).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for Ipv4Addr {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
Ok(Self::new(
u8::parse(parser)?,
u8::parse(parser)?,
u8::parse(parser)?,
u8::parse(parser)?,
))
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(4).map_err(Into::into)
}
}
impl<T: AsRef<[u8]>> Parse<T> for Ipv6Addr {
fn parse(parser: &mut Parser<T>) -> Result<Self, ParseError> {
let mut buf = [0u8; 16];
parser.parse_buf(&mut buf)?;
Ok(buf.into())
}
fn skip(parser: &mut Parser<T>) -> Result<(), ParseError> {
parser.advance(16).map_err(Into::into)
}
}
pub trait Compose {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf>;
fn compose_canonical<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
self.compose(target)
}
}
impl<'a, C: Compose + ?Sized> Compose for &'a C {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
(*self).compose(target)
}
fn compose_canonical<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
(*self).compose_canonical(target)
}
}
impl Compose for i8 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&[*self as u8])
}
}
impl Compose for u8 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&[*self])
}
}
impl Compose for i16 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.to_be_bytes())
}
}
impl Compose for u16 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.to_be_bytes())
}
}
impl Compose for i32 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.to_be_bytes())
}
}
impl Compose for u32 {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.to_be_bytes())
}
}
impl Compose for Ipv4Addr {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.octets())
}
}
impl Compose for Ipv6Addr {
fn compose<T: OctetsBuilder + AsMut<[u8]>>(
&self,
target: &mut T,
) -> Result<(), ShortBuf> {
target.append_slice(&self.octets())
}
}
#[macro_export]
macro_rules! octets_array {
( $vis:vis $name:ident => $len:expr) => {
#[derive(Clone)]
$vis struct $name {
octets: [u8; $len],
len: usize
}
impl $name {
pub fn new() -> Self {
Default::default()
}
pub fn as_slice(&self) -> &[u8] {
&self.octets[..self.len]
}
pub fn as_slice_mut(&mut self) -> &mut [u8] {
&mut self.octets[..self.len]
}
}
impl Default for $name {
fn default() -> Self {
$name {
octets: [0; $len],
len: 0
}
}
}
impl<'a> TryFrom<&'a [u8]> for $name {
type Error = ShortBuf;
fn try_from(src: &'a [u8]) -> Result<Self, ShortBuf> {
let len = src.len();
if len > $len {
Err(ShortBuf)
}
else {
let mut res = Self::default();
res.octets[..len].copy_from_slice(src);
res.len = len;
Ok(res)
}
}
}
impl core::ops::Deref for $name {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.as_slice()
}
}
impl core::ops::DerefMut for $name {
fn deref_mut(&mut self) -> &mut [u8] {
self.as_slice_mut()
}
}
impl AsRef<[u8]> for $name {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl AsMut<[u8]> for $name {
fn as_mut(&mut self) -> &mut [u8] {
self.as_slice_mut()
}
}
impl borrow::Borrow<[u8]> for $name {
fn borrow(&self) -> &[u8] {
self.as_slice()
}
}
impl borrow::BorrowMut<[u8]> for $name {
fn borrow_mut(&mut self) -> &mut [u8] {
self.as_slice_mut()
}
}
impl $crate::base::octets::OctetsBuilder for $name {
type Octets = Self;
fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> {
if slice.len() > $len - self.len {
Err(ShortBuf)
}
else {
let end = self.len + slice.len();
self.octets[self.len..end].copy_from_slice(slice);
self.len = end;
Ok(())
}
}
fn truncate(&mut self, len: usize) {
if len < self.len {
self.len = len
}
}
fn freeze(self) -> Self::Octets {
self
}
fn len(&self) -> usize {
self.len
}
fn is_empty(&self) -> bool {
self.len == 0
}
}
impl $crate::base::octets::EmptyBuilder for $name {
fn empty() -> Self {
$name {
octets: [0; $len],
len: 0
}
}
fn with_capacity(_capacity: usize) -> Self {
Self::empty()
}
}
impl $crate::base::octets::IntoBuilder for $name {
type Builder = Self;
fn into_builder(self) -> Self::Builder {
self
}
}
impl $crate::base::octets::FromBuilder for $name {
type Builder = Self;
fn from_builder(builder: Self::Builder) -> Self {
builder
}
}
impl<T: AsRef<[u8]>> PartialEq<T> for $name {
fn eq(&self, other: &T) -> bool {
self.as_slice().eq(other.as_ref())
}
}
impl Eq for $name { }
impl<T: AsRef<[u8]>> PartialOrd<T> for $name {
fn partial_cmp(&self, other: &T) -> Option<Ordering> {
self.as_slice().partial_cmp(other.as_ref())
}
}
impl Ord for $name {
fn cmp(&self, other: &Self) -> Ordering {
self.as_slice().cmp(other.as_slice())
}
}
impl hash::Hash for $name {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_slice().hash(state)
}
}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple(stringify!($name))
.field(&self.as_slice())
.finish()
}
}
}
}
octets_array!(pub Octets32 => 32);
octets_array!(pub Octets64 => 64);
octets_array!(pub Octets128 => 128);
octets_array!(pub Octets256 => 256);
octets_array!(pub Octets512 => 512);
octets_array!(pub Octets1024 => 1024);
octets_array!(pub Octets2048 => 2048);
octets_array!(pub Octets4096 => 4096);
#[cfg(feature = "smallvec")]
pub type OctetsVec = SmallVec<[u8; 24]>;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ShortBuf;
impl fmt::Display for ShortBuf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("buffer size exceeded")
}
}
#[cfg(feature = "std")]
impl std::error::Error for ShortBuf {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ParseError {
ShortInput,
Form(FormError),
}
impl ParseError {
pub fn form_error(msg: &'static str) -> Self {
FormError::new(msg).into()
}
}
impl From<FormError> for ParseError {
fn from(err: FormError) -> Self {
ParseError::Form(err)
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ParseError::ShortInput => f.write_str("unexpected end of input"),
ParseError::Form(ref err) => err.fmt(f),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct FormError(&'static str);
impl FormError {
pub fn new(msg: &'static str) -> Self {
FormError(msg)
}
}
impl fmt::Display for FormError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.0)
}
}
#[cfg(feature = "std")]
impl std::error::Error for FormError {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn pos_seek_remaining() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek(1).unwrap(), b"0");
assert_eq!(parser.pos(), 0);
assert_eq!(parser.remaining(), 10);
assert_eq!(parser.seek(2), Ok(()));
assert_eq!(parser.pos(), 2);
assert_eq!(parser.remaining(), 8);
assert_eq!(parser.peek(1).unwrap(), b"2");
assert_eq!(parser.seek(10), Ok(()));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.remaining(), 0);
assert_eq!(parser.peek_all(), b"");
assert_eq!(parser.seek(11), Err(ParseError::ShortInput));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.remaining(), 0);
}
#[test]
fn peek_check_len() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek(2), Ok(b"01".as_ref()));
assert_eq!(parser.check_len(2), Ok(()));
assert_eq!(parser.peek(10), Ok(b"0123456789".as_ref()));
assert_eq!(parser.check_len(10), Ok(()));
assert_eq!(parser.peek(11), Err(ParseError::ShortInput));
assert_eq!(parser.check_len(11), Err(ParseError::ShortInput));
parser.advance(2).unwrap();
assert_eq!(parser.peek(2), Ok(b"23".as_ref()));
assert_eq!(parser.check_len(2), Ok(()));
assert_eq!(parser.peek(8), Ok(b"23456789".as_ref()));
assert_eq!(parser.check_len(8), Ok(()));
assert_eq!(parser.peek(9), Err(ParseError::ShortInput));
assert_eq!(parser.check_len(9), Err(ParseError::ShortInput));
}
#[test]
fn peek_all() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek_all(), b"0123456789");
parser.advance(2).unwrap();
assert_eq!(parser.peek_all(), b"23456789");
}
#[test]
fn advance() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.pos(), 0);
assert_eq!(parser.peek(1).unwrap(), b"0");
assert_eq!(parser.advance(2), Ok(()));
assert_eq!(parser.pos(), 2);
assert_eq!(parser.peek(1).unwrap(), b"2");
assert_eq!(parser.advance(9), Err(ParseError::ShortInput));
assert_eq!(parser.advance(8), Ok(()));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.peek_all(), b"");
}
#[test]
fn parse_octets() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.parse_octets(2).unwrap(), b"01");
assert_eq!(parser.parse_octets(2).unwrap(), b"23");
assert_eq!(parser.parse_octets(7), Err(ParseError::ShortInput));
assert_eq!(parser.parse_octets(6).unwrap(), b"456789");
}
#[test]
fn parse_buf() {
let mut parser = Parser::from_static(b"0123456789");
let mut buf = [0u8; 2];
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"01");
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"23");
let mut buf = [0u8; 7];
assert_eq!(parser.parse_buf(&mut buf), Err(ParseError::ShortInput));
let mut buf = [0u8; 6];
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"456789");
}
#[test]
fn parse_i8() {
let mut parser = Parser::from_static(b"\x12\xd6");
assert_eq!(parser.parse_i8(), Ok(0x12));
assert_eq!(parser.parse_i8(), Ok(-42));
assert_eq!(parser.parse_i8(), Err(ParseError::ShortInput));
}
#[test]
fn parse_u8() {
let mut parser = Parser::from_static(b"\x12\xd6");
assert_eq!(parser.parse_u8(), Ok(0x12));
assert_eq!(parser.parse_u8(), Ok(0xd6));
assert_eq!(parser.parse_u8(), Err(ParseError::ShortInput));
}
#[test]
fn parse_i16() {
let mut parser = Parser::from_static(b"\x12\x34\xef\x6e\0");
assert_eq!(parser.parse_i16(), Ok(0x1234));
assert_eq!(parser.parse_i16(), Ok(-4242));
assert_eq!(parser.parse_i16(), Err(ParseError::ShortInput));
}
#[test]
fn parse_u16() {
let mut parser = Parser::from_static(b"\x12\x34\xef\x6e\0");
assert_eq!(parser.parse_u16(), Ok(0x1234));
assert_eq!(parser.parse_u16(), Ok(0xef6e));
assert_eq!(parser.parse_u16(), Err(ParseError::ShortInput));
}
#[test]
fn parse_i32() {
let mut parser =
Parser::from_static(b"\x12\x34\x56\x78\xfd\x78\xa8\x4e\0\0\0");
assert_eq!(parser.parse_i32(), Ok(0x12345678));
assert_eq!(parser.parse_i32(), Ok(-42424242));
assert_eq!(parser.parse_i32(), Err(ParseError::ShortInput));
}
#[test]
fn parse_u32() {
let mut parser =
Parser::from_static(b"\x12\x34\x56\x78\xfd\x78\xa8\x4e\0\0\0");
assert_eq!(parser.parse_u32(), Ok(0x12345678));
assert_eq!(parser.parse_u32(), Ok(0xfd78a84e));
assert_eq!(parser.parse_u32(), Err(ParseError::ShortInput));
}
}