Skip to content

Commit

Permalink
fixing the issue regarding serialization and deserialization of neste…
Browse files Browse the repository at this point in the history
…d enums would not match. (#5)
  • Loading branch information
vikalpacn authored Nov 22, 2022
1 parent 937ca76 commit 9f435a1
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bcs"
version = "0.1.3"
version = "0.1.4"
authors = ["Diem <[email protected]>"]
description = "Binary Canonical Serialization (BCS)"
repository = "https://github.com/diem/bcs"
Expand Down
12 changes: 6 additions & 6 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,22 +369,22 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
self.leave_named_container();
r
}

#[allow(clippy::needless_borrow)]
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let len = self.parse_length()?;
visitor.visit_seq(SeqDeserializer::new(&mut self, len))
}

#[allow(clippy::needless_borrow)]
fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_seq(SeqDeserializer::new(&mut self, len))
}

#[allow(clippy::needless_borrow)]
fn deserialize_tuple_struct<V>(
mut self,
name: &'static str,
Expand All @@ -399,15 +399,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
self.leave_named_container();
r
}

#[allow(clippy::needless_borrow)]
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let len = self.parse_length()?;
visitor.visit_map(MapDeserializer::new(&mut self, len))
}

#[allow(clippy::needless_borrow)]
fn deserialize_struct<V>(
mut self,
name: &'static str,
Expand Down Expand Up @@ -464,7 +464,7 @@ struct SeqDeserializer<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
remaining: usize,
}

#[allow(clippy::needless_borrow)]
impl<'a, 'de> SeqDeserializer<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, remaining: usize) -> Self {
Self { de, remaining }
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::fmt;
use thiserror::Error;

pub type Result<T, E = Error> = std::result::Result<T, E>;

#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Debug, Error, PartialEq)]
pub enum Error {
#[error("unexpected end of input")]
Expand Down
3 changes: 2 additions & 1 deletion src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,11 @@ where

fn serialize_unit_variant(
mut self,
_name: &'static str,
name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.enter_named_container(name)?;
self.output_variant_index(variant_index)
}

Expand Down
75 changes: 57 additions & 18 deletions tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,26 +570,38 @@ fn serde_known_vector() {
}

#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
struct List {
next: Option<(usize, Box<List>)>,
struct List<T> {
value: T,
next: Option<Box<List<T>>>,
}

impl List {
fn empty() -> Self {
Self { next: None }
impl<T> List<T> {
fn head(value: T) -> Self {
Self { value, next: None }
}

fn cons(value: usize, tail: List) -> Self {
fn cons(value: T, tail: List<T>) -> Self {
Self {
next: Some((value, Box::new(tail))),
value,
next: Some(Box::new(tail)),
}
}
}
impl<T: Clone> List<T> {
fn repeat(len: usize, value: T) -> Self {
if len == 0 {
Self::head(value)
} else {
Self::cons(value.clone(), Self::repeat(len - 1, value))
}
}
}

impl List<usize> {
fn integers(len: usize) -> Self {
if len == 0 {
Self::empty()
Self::head(0)
} else {
Self::cons(len - 1, Self::integers(len - 1))
Self::cons(len, Self::integers(len - 1))
}
}
}
Expand All @@ -601,31 +613,30 @@ fn test_recursion_limit() {
assert_eq!(
b1,
vec![
1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0
4, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
assert_eq!(from_bytes::<List>(&b1).unwrap(), l1);
assert_eq!(from_bytes::<List<_>>(&b1).unwrap(), l1);

let l2 = List::integers(MAX_CONTAINER_DEPTH - 1);
let b2 = to_bytes(&l2).unwrap();
assert_eq!(from_bytes::<List>(&b2).unwrap(), l2);

assert_eq!(from_bytes::<List<_>>(&b2).unwrap(), l2);
let l3 = List::integers(MAX_CONTAINER_DEPTH);
assert_eq!(
to_bytes(&l3),
Err(Error::ExceededContainerDepthLimit("List"))
);
let mut b3 = vec![1, 243, 1, 0, 0, 0, 0, 0, 0];
let mut b3 = vec![244, 1, 0, 0, 0, 0, 0, 0, 1];
b3.extend(b2);
assert_eq!(
from_bytes::<List>(&b3),
from_bytes::<List<usize>>(&b3),
Err(Error::ExceededContainerDepthLimit("List"))
);

let b2_pair = to_bytes(&(&l2, &l2)).unwrap();
assert_eq!(
from_bytes::<(List, List)>(&b2_pair).unwrap(),
from_bytes::<(List<_>, List<_>)>(&b2_pair).unwrap(),
(l2.clone(), l2.clone())
);
assert_eq!(
Expand All @@ -641,3 +652,31 @@ fn test_recursion_limit() {
Err(Error::ExceededContainerDepthLimit("List"))
);
}
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, Debug)]
enum EnumA {
ValueA,
}

#[test]
fn test_recursion_limit_enum() {
let l1 = List::repeat(6, EnumA::ValueA);
let b1 = to_bytes(&l1).unwrap();
assert_eq!(b1, vec![0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],);
assert_eq!(from_bytes::<List<_>>(&b1).unwrap(), l1);

let l2 = List::repeat(MAX_CONTAINER_DEPTH - 2, EnumA::ValueA);
let b2 = to_bytes(&l2).unwrap();
assert_eq!(from_bytes::<List<_>>(&b2).unwrap(), l2);

let l3 = List::repeat(MAX_CONTAINER_DEPTH - 1, EnumA::ValueA);
assert_eq!(
to_bytes(&l3),
Err(Error::ExceededContainerDepthLimit("EnumA"))
);
let mut b3 = vec![0, 1];
b3.extend(b2);
assert_eq!(
from_bytes::<List<EnumA>>(&b3),
Err(Error::ExceededContainerDepthLimit("EnumA"))
);
}

0 comments on commit 9f435a1

Please sign in to comment.