Skip to content

Commit

Permalink
simplify (de)serialize for octets
Browse files Browse the repository at this point in the history
  • Loading branch information
tertsdiepraam committed Jun 26, 2024
1 parent ce666aa commit 31f62dd
Showing 1 changed file with 22 additions and 148 deletions.
170 changes: 22 additions & 148 deletions src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,24 @@
//! [Serde](https://serde.rs/) supports native serialization of octets
//! sequences. However, because of missing specialization, it has to
//! serialize the octets slices and vec as literal sequences of `u8`s. In
//! order to allow octets sequences their own native serialization, the crate
//! defines two traits [`SerializeOctets`] and [`DeserializeOctets`] if
//! built with the `serde` feature enabled.
//! order to allow octets sequences their own native deserialization, the
//! crate defines the trait [`DeserializeOctets`] if built with the `serde`
//! feature enabled.
#![cfg(feature = "serde")]

use core::fmt;
use core::marker::PhantomData;
use serde::de::Visitor;

pub fn serialize<Octs, S>(octs: &Octs, serializer: S) -> Result<S::Ok, S::Error>
pub fn serialize<Octs, S>(
octs: &Octs,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
Octs: AsRef<[u8]> + ?Sized,
{
octs.as_ref().serialize_octets(serializer)
serializer.serialize_bytes(octs.as_ref())
}

pub fn deserialize<'de, Octs, D>(deserializer: D) -> Result<Octs, D::Error>
Expand All @@ -28,109 +31,38 @@ where
Octs::deserialize_octets(deserializer)
}

//------------ SerializeOctets -----------------------------------------------

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 SerializeOctets for [u8] {
fn serialize_octets<S: serde::Serializer>(
&self, serializer: S
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(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())
}
}


//------------ AsSerializedOctets --------------------------------------------
//------------ OctetsSerializer --------------------------------------------

/// A wrapper forcing a value to serialize through its octets.
///
/// This type can be used where a `Serialize` value is required.
pub struct AsSerializedOctets<'a, T: ?Sized>(&'a T);
pub struct AsSerializedOctets<'a>(&'a [u8]);

impl<'a, T: SerializeOctets> serde::Serialize for AsSerializedOctets<'a, T>
where
T: SerializeOctets + ?Sized
{
impl<'a> serde::Serialize for AsSerializedOctets<'a> {
fn serialize<S: serde::Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
self.0.serialize_octets(serializer)
serialize(&self.0, serializer)
}
}

impl<'a, T: AsRef<[u8]> + ?Sized> From<&'a T> for AsSerializedOctets<'a> {
fn from(value: &'a T) -> Self {
AsSerializedOctets(value.as_ref())
}
}

//------------ DeserializeOctets ---------------------------------------------

pub trait DeserializeOctets<'de>: Sized {
type Visitor: Visitor<'de, Value = Self>;

fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D
) -> Result<Self, D::Error>;
deserializer: D,
) -> Result<Self, D::Error> {
Self::deserialize_with_visitor(deserializer, Self::visitor())
}

fn deserialize_with_visitor<
D: serde::Deserializer<'de>,
Expand All @@ -146,12 +78,6 @@ pub trait DeserializeOctets<'de>: Sized {
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,
Expand All @@ -175,7 +101,7 @@ impl<'de> DeserializeOctets<'de> for std::borrow::Cow<'de, [u8]> {
fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
Self::deserialize_with_visitor(deserializer, Self::visitor())
}

fn deserialize_with_visitor<D, V>(
Expand All @@ -198,12 +124,6 @@ impl<'de> DeserializeOctets<'de> for std::borrow::Cow<'de, [u8]> {
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,
Expand All @@ -224,12 +144,6 @@ impl<'de> DeserializeOctets<'de> for std::vec::Vec<u8> {
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,
Expand All @@ -253,12 +167,6 @@ where
{
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,
Expand All @@ -279,12 +187,6 @@ where
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,
Expand All @@ -309,16 +211,6 @@ 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>
Expand Down Expand Up @@ -349,16 +241,6 @@ 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")]
Expand Down Expand Up @@ -387,7 +269,6 @@ where
}
}


//------------ HeaplessVisitor -----------------------------------------------

#[cfg(feature = "heapless")]
Expand All @@ -398,13 +279,6 @@ 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")]
Expand Down

0 comments on commit 31f62dd

Please sign in to comment.