Skip to content

Commit

Permalink
Fix serialization of newtype structs, simplify serialization of newty…
Browse files Browse the repository at this point in the history
…pe and tuple variants (#104)

* Add unit tests for differentiating between newtype and tuple structs and variants

* Fix serialization of newtype struct, and simplify serialization of newtype and tuple variants
  • Loading branch information
Árpád Goretity  authored and zonyitoo committed Aug 11, 2018
1 parent 4058d4f commit 83351d1
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 14 deletions.
20 changes: 6 additions & 14 deletions src/encoder/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,7 @@ impl Serializer for Encoder {
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> EncoderResult<Bson>
where T: Serialize
{
let mut ser = TupleStructSerializer { inner: Array::new(), };
ser.serialize_field(value)?;
ser.end()
value.serialize(self)
}

#[inline]
Expand All @@ -221,10 +219,9 @@ impl Serializer for Encoder {
-> EncoderResult<Bson>
where T: Serialize
{
let mut ser = TupleVariantSerializer { inner: Array::new(),
name: variant, };
ser.serialize_field(value)?;
ser.end()
let mut newtype_variant = Document::new();
newtype_variant.insert(variant, to_bson(value)?);
Ok(newtype_variant.into())
}

#[inline]
Expand Down Expand Up @@ -350,13 +347,8 @@ impl SerializeTupleVariant for TupleVariantSerializer {

fn end(self) -> EncoderResult<Bson> {
let mut tuple_variant = Document::new();
if self.inner.len() == 1 {
tuple_variant.insert(self.name, self.inner.into_iter().next().unwrap());
} else {
tuple_variant.insert(self.name, Bson::Array(self.inner));
}

Ok(Bson::Document(tuple_variant))
tuple_variant.insert(self.name, self.inner);
Ok(tuple_variant.into())
}
}

Expand Down
72 changes: 72 additions & 0 deletions tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,75 @@ fn test_serde_bytes() {
let f = bson::from_bson::<Foo>(b).unwrap();
assert_eq!(x, f);
}

#[test]
fn test_serde_newtype_struct() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Email(String);

let email_1 = Email(String::from("bson@serde.rs"));
let b = bson::to_bson(&email_1).unwrap();
assert_eq!(b, Bson::String(email_1.0));

let s = String::from("root@localho.st");
let de = Bson::String(s.clone());
let email_2 = bson::from_bson::<Email>(de).unwrap();
assert_eq!(email_2, Email(s));
}

#[test]
fn test_serde_tuple_struct() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Name(String, String); // first, last

let name_1 = Name(String::from("Graydon"), String::from("Hoare"));
let b = bson::to_bson(&name_1).unwrap();
assert_eq!(b, bson!([
name_1.0.clone(),
name_1.1.clone(),
]));

let (first, last) = (String::from("Donald"), String::from("Knuth"));
let de = bson!([first.clone(), last.clone()]);
let name_2 = bson::from_bson::<Name>(de).unwrap();
assert_eq!(name_2, Name(first, last));
}

#[test]
fn test_serde_newtype_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "value")]
enum Number {
Int(i64),
Float(f64),
}

let n = 42;
let num_1 = Number::Int(n);
let b = bson::to_bson(&num_1).unwrap();
assert_eq!(b, bson!({ "type": "Int", "value": n }));

let x = 1337.0;
let de = bson!({ "type": "Float", "value": x });
let num_2 = bson::from_bson::<Number>(de).unwrap();
assert_eq!(num_2, Number::Float(x));
}

#[test]
fn test_serde_tuple_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Point {
TwoDim(f64, f64),
ThreeDim(f64, f64, f64),
}

let (x1, y1) = (3.14, -2.71);
let p1 = Point::TwoDim(x1, y1);
let b = bson::to_bson(&p1).unwrap();
assert_eq!(b, bson!({ "TwoDim": [x1, y1] }));

let (x2, y2, z2) = (0.0, -13.37, 4.2);
let de = bson!({ "ThreeDim": [x2, y2, z2] });
let p2 = bson::from_bson::<Point>(de).unwrap();
assert_eq!(p2, Point::ThreeDim(x2, y2, z2));
}

0 comments on commit 83351d1

Please sign in to comment.