Skip to content

Commit

Permalink
Added examples showing when tuples are valid
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-F-Bryan committed Aug 23, 2017
1 parent 013e04a commit 19e9e92
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 15 deletions.
71 changes: 59 additions & 12 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ use serde::ser::{self, Impossible, Serialize};
use error::{Error, ErrorKind, Result};
use self::var::{Map, Struct};
use self::seq::Seq;
use self::tuples::Tuple;

mod var;
mod seq;
mod helpers;
mod tuples;


/// A convenience method for serializing some object to a buffer.
Expand Down Expand Up @@ -116,7 +118,7 @@ where
type Error = Error;

type SerializeSeq = Seq<'w, W>;
type SerializeTuple = Impossible<Self::Ok, Self::Error>;
type SerializeTuple = Tuple<'w, W>;
type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
type SerializeMap = Map<'w, W>;
Expand Down Expand Up @@ -241,9 +243,7 @@ where
}

fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
Err(
ErrorKind::UnsupportedOperation("serialize_tuple".to_string()).into(),
)
Ok(Tuple::new(self))
}

fn serialize_tuple_struct(
Expand Down Expand Up @@ -284,7 +284,9 @@ where
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
Err(ErrorKind::UnsupportedOperation("serialize_struct_variant".to_string()).into())
Err(
ErrorKind::UnsupportedOperation("serialize_struct_variant".to_string()).into(),
)
}
}

Expand Down Expand Up @@ -410,20 +412,65 @@ mod tests {
let inputs = vec![Foo, Foo, Foo];
let should_be = "<Foo></Foo><Foo></Foo><Foo></Foo>";

let mut buffer = Vec::new();
inputs.serialize(&mut Serializer::new(&mut buffer)).unwrap();

let got = String::from_utf8(buffer).unwrap();
let got = to_string(&inputs).unwrap();
assert_eq!(got, should_be);
}

#[test]
fn serializing_a_list_of_primitives_is_an_error() {
let dodgy = vec![1, 2, 3, 4, 5];
assert!(to_string(&dodgy).is_err());
}

let mut buffer = Vec::new();
let got = dodgy.serialize(&mut Serializer::new(&mut buffer));
#[test]
fn serializing_a_list_of_tuples_is_an_error() {
let dodgy = vec![(1, 2), (3, 4)];

assert!(to_string(&dodgy).is_err());
}

#[test]
fn serialize_list_of_newtype_enums() {
#[derive(Serialize)]
enum Foo {
A(u32),
B(bool),
C(Box<Foo>)
}

let f = vec![Foo::A(42), Foo::B(true), Foo::C(Box::new(Foo::B(false)))];
let should_be = "<A>42</A><B>true</B><C><B>false</B></C>";

let got = to_string(&f).unwrap();
assert_eq!(got, should_be);
}

#[test]
fn serialize_tuple_containing_non_primitive_types() {
#[derive(Serialize)]
struct Foo;
#[derive(Serialize)]
struct Bar;

let a = (Foo, Bar);
let should_be = "<Foo></Foo><Bar></Bar>";

let got = to_string(&a).unwrap();
assert_eq!(got, should_be);
}

#[test]
fn serialize_tuple_of_primitives_is_error() {
let value = (5, false);
assert!(to_string(&value).is_err());
}

#[test]
fn serialize_tuple_with_at_least_1_primitive_is_error() {
#[derive(Serialize)]
struct Foo;

assert!(got.is_err());
let value = (5, Foo);
assert!(to_string(&value).is_err());
}
}
6 changes: 3 additions & 3 deletions src/ser/seq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ impl<'a, W: Write> SerializeSeq for Seq<'a, W> {
type Ok = ();
type Error = Error;

fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok>
fn serialize_element<T>(&mut self, value: &T) -> Result<Self::Ok>
where
T: Serialize,
T: Serialize + ?Sized,
{
if helpers::is_wrapped(value) {
value.serialize(&mut *self.parent)
} else {
Err(SerError::custom(
"Cannot serialize a sequence of primitives",
"Cannot serialize a sequence of primitives. Please wrap them in newtypes",
))
}
}
Expand Down
45 changes: 45 additions & 0 deletions src/ser/tuples.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::io::Write;
use serde::ser::{Error as SerError, Serialize, SerializeTuple};

use ser::Serializer;
use ser::helpers;
use error::Error;

pub struct Tuple<'a, W: 'a + Write> {
parent: &'a mut Serializer<W>,
}


impl<'w, W> Tuple<'w, W>
where
W: 'w + Write,
{
pub fn new(parent: &'w mut Serializer<W>) -> Tuple<'w, W> {
Tuple { parent }
}
}

impl<'w, W> SerializeTuple for Tuple<'w, W>
where
W: 'w + Write
{
type Ok = ();
type Error = Error;

fn serialize_element<T>(&mut self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize + ?Sized
{
if helpers::is_wrapped(value) {
value.serialize(&mut *self.parent)
} else {
Err(SerError::custom(
"Tuples can't contain primitive types. Please wrap primitives in a newtype.",
))
}
}

fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(())
}
}

0 comments on commit 19e9e92

Please sign in to comment.