Skip to content

Commit

Permalink
Hack to use bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Apr 17, 2024
1 parent 1d9856b commit 6dd81ee
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 10 deletions.
171 changes: 171 additions & 0 deletions rmp-serde/src/bytes.rs
@@ -0,0 +1,171 @@
/// Hacky serializer that only allows `u8`

use std::fmt;
use serde::ser::Impossible;
use serde::Serialize;

pub(crate) struct OnlyBytes;
pub(crate) struct Nope;

impl std::error::Error for Nope {
}

impl std::fmt::Display for Nope {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}

impl std::fmt::Debug for Nope {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}

impl serde::ser::Error for Nope {
fn custom<T: fmt::Display>(_: T) -> Self {
Self
}
}

impl serde::de::Error for Nope {
fn custom<T: fmt::Display>(_: T) -> Self {
Self
}
}

impl serde::Serializer for OnlyBytes {
type Ok = u8;
type Error = Nope;
type SerializeSeq = Impossible<u8, Nope>;
type SerializeTuple = Impossible<u8, Nope>;
type SerializeTupleStruct = Impossible<u8, Nope>;
type SerializeTupleVariant = Impossible<u8, Nope>;
type SerializeMap = Impossible<u8, Nope>;
type SerializeStruct = Impossible<u8, Nope>;
type SerializeStructVariant = Impossible<u8, Nope>;

fn serialize_u8(self, val: u8) -> Result<u8, Nope> {
Ok(val)
}

fn serialize_bool(self, _: bool) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_i8(self, _: i8) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_i16(self, _: i16) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_i32(self, _: i32) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_i64(self, _: i64) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_u16(self, _: u16) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_u32(self, _: u32) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_u64(self, _: u64) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_f32(self, _: f32) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_f64(self, _: f64) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_char(self, _: char) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_str(self, _: &str) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_bytes(self, _: &[u8]) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_none(self) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_some<T: ?Sized>(self, _: &T) -> Result<u8, Nope> where T: Serialize {
Err(Nope)
}

fn serialize_unit(self) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_unit_struct(self, _: &'static str) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<u8, Nope> {
Err(Nope)
}

fn serialize_newtype_struct<T: ?Sized>(self, _: &'static str, _: &T) -> Result<u8, Nope> where T: Serialize {
Err(Nope)
}

fn serialize_newtype_variant<T: ?Sized>(self, _: &'static str, _: u32, _: &'static str, _: &T) -> Result<u8, Nope> where T: Serialize {
Err(Nope)
}

fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Nope> {
Err(Nope)
}

fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Nope> {
Err(Nope)
}

fn serialize_tuple_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeTupleStruct, Nope> {
Err(Nope)
}

fn serialize_tuple_variant(self, _: &'static str, _: u32, _: &'static str, _: usize) -> Result<Self::SerializeTupleVariant, Nope> {
Err(Nope)
}

fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Nope> {
Err(Nope)
}

fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct, Nope> {
Err(Nope)
}

fn serialize_struct_variant(self, _: &'static str, _: u32, _: &'static str, _: usize) -> Result<Self::SerializeStructVariant, Nope> {
Err(Nope)
}

fn collect_seq<I>(self, _: I) -> Result<u8, Nope> where I: IntoIterator, <I as IntoIterator>::Item: Serialize {
Err(Nope)
}

fn collect_map<K, V, I>(self, _: I) -> Result<u8, Nope> where K: Serialize, V: Serialize, I: IntoIterator<Item = (K, V)> {
Err(Nope)
}

fn collect_str<T: ?Sized>(self, _: &T) -> Result<u8, Nope> where T: fmt::Display {
Err(Nope)
}
}
54 changes: 54 additions & 0 deletions rmp-serde/src/config.rs
Expand Up @@ -9,6 +9,8 @@ pub trait SerializerConfig: sealed::SerializerConfig {}
impl<T: sealed::SerializerConfig> SerializerConfig for T {}

pub(crate) mod sealed {
use crate::config::BytesMode;

/// This is the inner trait - the real `SerializerConfig`.
///
/// This hack disallows external implementations and usage of `SerializerConfig` and thus
Expand All @@ -20,20 +22,46 @@ pub(crate) mod sealed {

/// String struct fields
fn is_named(&self) -> bool;
fn bytes(&self) -> BytesMode;
}
}

#[derive(Copy, Clone, Debug)]
pub(crate) struct RuntimeConfig {
pub(crate) is_human_readable: bool,
pub(crate) is_named: bool,
pub(crate) bytes: BytesMode,
}

/// When to encode `[u8]` as `bytes` rather than a sequence
/// of integers. Serde without `serde_bytes` has trouble
/// using `bytes`, and this is hack to force it. It may
/// break some data types.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
pub enum BytesMode {
/// Use bytes only when Serde requires it
/// (typically only when `serde_bytes` is used)
#[default]
Normal,
/// Use bytes for slices, `Vec`, and a few other types that
/// use `Iterator` in Serde.
///
/// This may break some implementations of `Deserialize`.
///
/// This does not include fixed-length arrays.
ForceIterables,
/// Use bytes for everything that looks like a container of `u8`.
/// This breaks some implementations of `Deserialize`.
ForceAll,
}

impl RuntimeConfig {
pub(crate) fn new(other: impl sealed::SerializerConfig) -> Self {
Self {
is_human_readable: other.is_human_readable(),
is_named: other.is_named(),
bytes: other.bytes(),
}
}
}
Expand All @@ -48,6 +76,11 @@ impl sealed::SerializerConfig for RuntimeConfig {
fn is_named(&self) -> bool {
self.is_named
}

#[inline]
fn bytes(&self) -> BytesMode {
self.bytes
}
}

/// The default serializer/deserializer configuration.
Expand All @@ -71,6 +104,11 @@ impl sealed::SerializerConfig for DefaultConfig {
fn is_human_readable(&self) -> bool {
false
}

#[inline(always)]
fn bytes(&self) -> BytesMode {
BytesMode::default()
}
}

/// Config wrapper, that overrides struct serialization by packing as a map with field names.
Expand Down Expand Up @@ -104,6 +142,10 @@ where
fn is_human_readable(&self) -> bool {
self.0.is_human_readable()
}

fn bytes(&self) -> BytesMode {
self.0.bytes()
}
}

/// Config wrapper that overrides struct serlization by packing as a tuple without field
Expand Down Expand Up @@ -132,6 +174,10 @@ where
fn is_human_readable(&self) -> bool {
self.0.is_human_readable()
}

fn bytes(&self) -> BytesMode {
self.0.bytes()
}
}

/// Config wrapper that overrides `Serializer::is_human_readable` and
Expand Down Expand Up @@ -160,6 +206,10 @@ where
fn is_human_readable(&self) -> bool {
true
}

fn bytes(&self) -> BytesMode {
self.0.bytes()
}
}

/// Config wrapper that overrides `Serializer::is_human_readable` and
Expand Down Expand Up @@ -188,4 +238,8 @@ where
fn is_human_readable(&self) -> bool {
false
}

fn bytes(&self) -> BytesMode {
self.0.bytes()
}
}

0 comments on commit 6dd81ee

Please sign in to comment.