Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add octseq::serde::serialize function #57

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,24 +257,14 @@ impl<const N: usize> fmt::Debug for Array<N> {
}
}


//--- SerializeOctets and DeserializeOctets

#[cfg(feature = "serde")]
impl<const N: usize> crate::serde::SerializeOctets for Array<N> {
fn serialize_octets<S: serde::Serializer>(
&self, serializer: S
) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(self.as_ref())
}
}
//--- DeserializeOctets

#[cfg(feature = "serde")]
impl<'de, const N: usize> crate::serde::DeserializeOctets<'de> for Array<N> {
type Visitor = ArrayVisitor<N>;

fn deserialize_octets<D: serde::Deserializer<'de>>(
deserializer: D
deserializer: D,
) -> Result<Self, D::Error> {
Self::visitor().deserialize(deserializer)
}
Expand Down
174 changes: 31 additions & 143 deletions src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,119 +3,66 @@
//! [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;


//------------ 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())
}
pub fn serialize<Octs, S>(
octs: &Octs,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
Octs: AsRef<[u8]> + ?Sized,
{
serializer.serialize_bytes(octs.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 fn deserialize<'de, Octs, D>(deserializer: D) -> Result<Octs, D::Error>
where
D: serde::Deserializer<'de>,
Octs: DeserializeOctets<'de>,
{
Octs::deserialize_octets(deserializer)
}


//------------ AsSerializedOctets --------------------------------------------

/// 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 @@ -131,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 @@ -160,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 @@ -183,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 @@ -209,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 @@ -238,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 @@ -264,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 @@ -294,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 @@ -334,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 @@ -372,7 +269,6 @@ where
}
}


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

#[cfg(feature = "heapless")]
Expand All @@ -383,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 All @@ -414,4 +303,3 @@ impl<'de, const N: usize> serde::de::Visitor<'de> for HeaplessVecVisitor<N> {
Ok(heapless::Vec::from_iter(value.iter().copied()))
}
}

Loading