feat(codegen): Add #[serde(serialize_with="...")]

This allows a field to be serialized with an expression instead
of the default serializer. This simplifies serializing a struct
or enum that contains an external type that doesn't implement
`serde::Serialize`. This expression is passed a variable
`serializer` that needs to be used to serialize the expression.
This commit is contained in:
Erick Tryzelaar
2016-02-15 17:39:46 -08:00
parent de89f95f31
commit 001cb7ab01
3 changed files with 196 additions and 1 deletions
+120
View File
@@ -1,3 +1,6 @@
use std::default::Default;
use serde::{Serialize, Serializer};
use token::{
Error,
Token,
@@ -11,12 +14,25 @@ trait Trait {
fn my_default() -> Self;
fn should_skip(&self) -> bool;
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
where S: Serializer;
}
impl Trait for i32 {
fn my_default() -> Self { 123 }
fn should_skip(&self) -> bool { *self == 123 }
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
where S: Serializer
{
if *self == 123 {
true.serialize(ser)
} else {
false.serialize(ser)
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
@@ -502,3 +518,107 @@ fn test_skip_serializing_enum() {
]
);
}
#[derive(Debug, PartialEq, Serialize)]
struct SerializeWithStruct<'a, B> where B: Trait {
a: &'a i8,
#[serde(serialize_with="self.b.serialize_with(serializer)")]
b: B,
}
#[test]
fn test_serialize_with_struct() {
let a = 1;
assert_ser_tokens(
&SerializeWithStruct {
a: &a,
b: 2,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(false),
Token::StructEnd,
]
);
assert_ser_tokens(
&SerializeWithStruct {
a: &a,
b: 123,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(true),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize)]
enum SerializeWithEnum<'a, B> where B: Trait {
Struct {
a: &'a i8,
#[serde(serialize_with="self.b.serialize_with(serializer)")]
b: B,
}
}
#[test]
fn test_serialize_with_enum() {
let a = 1;
assert_ser_tokens(
&SerializeWithEnum::Struct {
a: &a,
b: 2,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(false),
Token::EnumMapEnd,
]
);
assert_ser_tokens(
&SerializeWithEnum::Struct {
a: &a,
b: 123,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(true),
Token::EnumMapEnd,
]
);
}