mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 22:07:56 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f6a66a5537 | |||
| fd5ab8c5c8 | |||
| 39fa78e2ec | |||
| e18416ac7f | |||
| b63cc13f3a | |||
| 74b230c183 | |||
| 064241f03c | |||
| 32163cd53b | |||
| 3a5aa00262 | |||
| 7a3e3a61f4 | |||
| 517c2f79b7 | |||
| 3cde6fa333 | |||
| da7bb8e109 | |||
| 718822449f | |||
| 43624e8e7f | |||
| 4507eaec5b | |||
| b3212f4c2b | |||
| 6d25fc9dbb | |||
| a5d0703e44 | |||
| 0a32cea26e | |||
| da4e37d3f5 |
+4
-2
@@ -22,9 +22,11 @@ script:
|
|||||||
- |
|
- |
|
||||||
(cd serde && travis-cargo build) &&
|
(cd serde && travis-cargo build) &&
|
||||||
(cd serde && travis-cargo test) &&
|
(cd serde && travis-cargo test) &&
|
||||||
|
(cd serde && travis-cargo --only nightly test -- --features nightly-testing) &&
|
||||||
(cd serde_tests && travis-cargo test) &&
|
(cd serde_tests && travis-cargo test) &&
|
||||||
(cd serde_macros && travis-cargo --only nightly test) &&
|
(cd serde_tests && travis-cargo --only nightly test -- --features nightly-testing) &&
|
||||||
(cd serde_macros && travis-cargo --only nightly bench) &&
|
(cd serde_macros && travis-cargo --only nightly test -- --features nightly-testing) &&
|
||||||
|
(cd serde_macros && travis-cargo --only nightly bench -- --features nightly-testing) &&
|
||||||
(cd serde && travis-cargo --only stable doc) &&
|
(cd serde && travis-cargo --only stable doc) &&
|
||||||
(cd serde_codegen && travis-cargo --only stable doc)
|
(cd serde_codegen && travis-cargo --only stable doc)
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,28 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`build.rs`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
extern crate syntex;
|
||||||
|
extern crate serde_codegen;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
let src = Path::new("src/main.rs.in");
|
||||||
|
let dst = Path::new(&out_dir).join("main.rs");
|
||||||
|
|
||||||
|
let mut registry = syntex::Registry::new();
|
||||||
|
|
||||||
|
serde_codegen::register(&mut registry);
|
||||||
|
registry.expand("", &src, &dst).unwrap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
This also produces:
|
This also produces:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -579,6 +601,69 @@ impl serde::de::Visitor for PointVisitor {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Design Considerations and tradeoffs for Serializers and Deserializers
|
||||||
|
=====================================================================
|
||||||
|
|
||||||
|
Serde serialization and deserialization implementations are written in such a
|
||||||
|
way that they err on being able to represent more values, and also provide
|
||||||
|
better error messages when they are passed an incorrect type to deserialize
|
||||||
|
from. For example, by default, it is a syntax error to deserialize a `String`
|
||||||
|
into an `Option<String>`. This is implemented such that it is possible to
|
||||||
|
distinguish between the values `None` and `Some(())`, if the serialization
|
||||||
|
format supports option types.
|
||||||
|
|
||||||
|
However, many formats do not have option types, and represents optional values
|
||||||
|
as either a `null`, or some other value. Serde `Serializer`s and
|
||||||
|
`Deserializer`s can opt-in support for this. For serialization, this is pretty
|
||||||
|
easy. Simply implement these methods:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
...
|
||||||
|
|
||||||
|
fn visit_none(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.visit_unit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_some<T>(&mut self, value: T) -> Result<(), Self::Error> {
|
||||||
|
value.serialize(self)
|
||||||
|
}
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
For deserialization, this can be implemented by way of the
|
||||||
|
`Deserializer::visit_option` hook, which presumes that there is some ability to peek at what is the
|
||||||
|
next value in the serialized token stream. This following example is from
|
||||||
|
[serde_tests::TokenDeserializer](https://github.com/serde-rs/serde/blob/master/serde_tests/tests/token.rs#L435-L454),
|
||||||
|
where it checks to see if the next value is an `Option`, a `()`, or some other
|
||||||
|
value:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
...
|
||||||
|
|
||||||
|
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
|
match self.tokens.peek() {
|
||||||
|
Some(&Token::Option(false)) => {
|
||||||
|
self.tokens.next();
|
||||||
|
visitor.visit_none()
|
||||||
|
}
|
||||||
|
Some(&Token::Option(true)) => {
|
||||||
|
self.tokens.next();
|
||||||
|
visitor.visit_some(self)
|
||||||
|
}
|
||||||
|
Some(&Token::Unit) => {
|
||||||
|
self.tokens.next();
|
||||||
|
visitor.visit_none()
|
||||||
|
}
|
||||||
|
Some(_) => visitor.visit_some(self),
|
||||||
|
None => Err(Error::EndOfStreamError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
Annotations
|
Annotations
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.6.10"
|
version = "0.6.14"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -10,12 +10,12 @@ readme = "../README.md"
|
|||||||
keywords = ["serde", "serialization"]
|
keywords = ["serde", "serialization"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
nightly = ["clippy"]
|
nightly-testing = ["clippy"]
|
||||||
num-bigint = ["num/bigint"]
|
num-bigint = ["num/bigint"]
|
||||||
num-complex = ["num/complex"]
|
num-complex = ["num/complex"]
|
||||||
num-impls = ["num-bigint", "num-complex", "num-rational"]
|
num-impls = ["num-bigint", "num-complex", "num-rational"]
|
||||||
num-rational = ["num/rational"]
|
num-rational = ["num/rational"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.0.36", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
num = { version = "^0.1.27", default-features = false }
|
num = { version = "^0.1.27", default-features = false }
|
||||||
|
|||||||
@@ -283,6 +283,13 @@ impl<
|
|||||||
> Visitor for OptionVisitor<T> {
|
> Visitor for OptionVisitor<T> {
|
||||||
type Value = Option<T>;
|
type Value = Option<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<Option<T>, E>
|
||||||
|
where E: Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_none<E>(&mut self) -> Result<Option<T>, E>
|
fn visit_none<E>(&mut self) -> Result<Option<T>, E>
|
||||||
where E: Error,
|
where E: Error,
|
||||||
@@ -755,7 +762,7 @@ impl Deserialize for path::PathBuf {
|
|||||||
fn deserialize<D>(deserializer: &mut D) -> Result<path::PathBuf, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<path::PathBuf, D::Error>
|
||||||
where D: Deserializer,
|
where D: Deserializer,
|
||||||
{
|
{
|
||||||
deserializer.visit(PathBufVisitor)
|
deserializer.visit_string(PathBufVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -403,6 +403,16 @@ pub trait Deserializer {
|
|||||||
self.visit_seq(visitor)
|
self.visit_seq(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method hints that the `Deserialize` type is expecting some sort of struct key mapping.
|
||||||
|
/// This allows deserializers to choose between &str, usize, or &[u8] to properly deserialize a
|
||||||
|
/// struct key.
|
||||||
|
#[inline]
|
||||||
|
fn visit_struct_field<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
self.visit(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
/// Specify a format string for the deserializer.
|
/// Specify a format string for the deserializer.
|
||||||
///
|
///
|
||||||
/// The deserializer format is used to determine which format
|
/// The deserializer format is used to determine which format
|
||||||
|
|||||||
+11
-10
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen"
|
name = "serde_codegen"
|
||||||
version = "0.6.10"
|
version = "0.6.14"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
@@ -11,17 +11,18 @@ keywords = ["serde", "serialization"]
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["with-syntex"]
|
default = ["with-syntex"]
|
||||||
nightly = ["clippy", "quasi_macros"]
|
nightly = ["quasi_macros"]
|
||||||
|
nightly-testing = ["clippy"]
|
||||||
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
quasi_codegen = { version = "^0.4.0", optional = true }
|
quasi_codegen = { version = "^0.7.0", optional = true }
|
||||||
syntex = { version = "^0.26.0", optional = true }
|
syntex = { version = "^0.29.0", optional = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aster = { version = "^0.10.0", default-features = false }
|
aster = { version = "^0.13.1", default-features = false }
|
||||||
clippy = { version = "^0.0.36", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
quasi = { version = "^0.4.0", default-features = false }
|
quasi = { version = "^0.7.0", default-features = false }
|
||||||
quasi_macros = { version = "^0.4.0", optional = true }
|
quasi_macros = { version = "^0.7.0", optional = true }
|
||||||
syntex = { version = "^0.26.0", optional = true }
|
syntex = { version = "^0.29.0", optional = true }
|
||||||
syntex_syntax = { version = "^0.26.0", optional = true }
|
syntex_syntax = { version = "^0.29.0", optional = true }
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl<'a> FieldAttrsBuilder<'a> {
|
|||||||
|
|
||||||
pub fn attr(mut self, attr: &ast::Attribute) -> Result<FieldAttrsBuilder<'a>, ()> {
|
pub fn attr(mut self, attr: &ast::Attribute) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||||
match attr.node.value.node {
|
match attr.node.value.node {
|
||||||
ast::MetaList(ref name, ref items) if name == &"serde" => {
|
ast::MetaItemKind::List(ref name, ref items) if name == &"serde" => {
|
||||||
attr::mark_used(&attr);
|
attr::mark_used(&attr);
|
||||||
for item in items {
|
for item in items {
|
||||||
self = try!(self.meta_item(item));
|
self = try!(self.meta_item(item));
|
||||||
@@ -167,15 +167,15 @@ impl<'a> FieldAttrsBuilder<'a> {
|
|||||||
|
|
||||||
pub fn meta_item(mut self, meta_item: &P<ast::MetaItem>) -> Result<FieldAttrsBuilder<'a>, ()> {
|
pub fn meta_item(mut self, meta_item: &P<ast::MetaItem>) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||||
match meta_item.node {
|
match meta_item.node {
|
||||||
ast::MetaNameValue(ref name, ref lit) if name == &"rename" => {
|
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"rename" => {
|
||||||
let expr = self.builder.expr().build_lit(P(lit.clone()));
|
let expr = self.builder.expr().build_lit(P(lit.clone()));
|
||||||
|
|
||||||
Ok(self.name(expr))
|
Ok(self.name(expr))
|
||||||
}
|
}
|
||||||
ast::MetaList(ref name, ref items) if name == &"rename" => {
|
ast::MetaItemKind::List(ref name, ref items) if name == &"rename" => {
|
||||||
for item in items {
|
for item in items {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::MetaNameValue(ref name, ref lit) => {
|
ast::MetaItemKind::NameValue(ref name, ref lit) => {
|
||||||
let name = self.builder.expr().str(name);
|
let name = self.builder.expr().str(name);
|
||||||
let expr = self.builder.expr().build_lit(P(lit.clone()));
|
let expr = self.builder.expr().build_lit(P(lit.clone()));
|
||||||
|
|
||||||
@@ -187,16 +187,16 @@ impl<'a> FieldAttrsBuilder<'a> {
|
|||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
ast::MetaWord(ref name) if name == &"default" => {
|
ast::MetaItemKind::Word(ref name) if name == &"default" => {
|
||||||
Ok(self.default())
|
Ok(self.default())
|
||||||
}
|
}
|
||||||
ast::MetaWord(ref name) if name == &"skip_serializing" => {
|
ast::MetaItemKind::Word(ref name) if name == &"skip_serializing" => {
|
||||||
Ok(self.skip_serializing_field())
|
Ok(self.skip_serializing_field())
|
||||||
}
|
}
|
||||||
ast::MetaWord(ref name) if name == &"skip_serializing_if_empty" => {
|
ast::MetaItemKind::Word(ref name) if name == &"skip_serializing_if_empty" => {
|
||||||
Ok(self.skip_serializing_field_if_empty())
|
Ok(self.skip_serializing_field_if_empty())
|
||||||
}
|
}
|
||||||
ast::MetaWord(ref name) if name == &"skip_serializing_if_none" => {
|
ast::MetaItemKind::Word(ref name) if name == &"skip_serializing_if_none" => {
|
||||||
Ok(self.skip_serializing_field_if_none())
|
Ok(self.skip_serializing_field_if_none())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -285,7 +285,7 @@ impl<'a> ContainerAttrsBuilder<'a> {
|
|||||||
|
|
||||||
pub fn attr(mut self, attr: &ast::Attribute) -> Result<Self, ()> {
|
pub fn attr(mut self, attr: &ast::Attribute) -> Result<Self, ()> {
|
||||||
match attr.node.value.node {
|
match attr.node.value.node {
|
||||||
ast::MetaList(ref name, ref items) if name == &"serde" => {
|
ast::MetaItemKind::List(ref name, ref items) if name == &"serde" => {
|
||||||
attr::mark_used(&attr);
|
attr::mark_used(&attr);
|
||||||
for item in items {
|
for item in items {
|
||||||
self = try!(self.meta_item(item));
|
self = try!(self.meta_item(item));
|
||||||
|
|||||||
+14
-14
@@ -37,8 +37,8 @@ pub fn expand_derive_deserialize(
|
|||||||
let builder = aster::AstBuilder::new().span(span);
|
let builder = aster::AstBuilder::new().span(span);
|
||||||
|
|
||||||
let generics = match item.node {
|
let generics = match item.node {
|
||||||
ast::ItemStruct(_, ref generics) => generics,
|
ast::ItemKind::Struct(_, ref generics) => generics,
|
||||||
ast::ItemEnum(_, ref generics) => generics,
|
ast::ItemKind::Enum(_, ref generics) => generics,
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(
|
cx.span_err(
|
||||||
meta_item.span,
|
meta_item.span,
|
||||||
@@ -92,7 +92,7 @@ fn deserialize_body(
|
|||||||
let _ = try!(field::container_attrs(cx, item));
|
let _ = try!(field::container_attrs(cx, item));
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemStruct(ref variant_data, _) => {
|
ast::ItemKind::Struct(ref variant_data, _) => {
|
||||||
deserialize_item_struct(
|
deserialize_item_struct(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -103,7 +103,7 @@ fn deserialize_body(
|
|||||||
variant_data,
|
variant_data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::ItemEnum(ref enum_def, _) => {
|
ast::ItemKind::Enum(ref enum_def, _) => {
|
||||||
deserialize_item_enum(
|
deserialize_item_enum(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -393,7 +393,7 @@ fn deserialize_seq(
|
|||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
fields: usize,
|
fields: usize,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let let_values: Vec<P<ast::Stmt>> = (0 .. fields)
|
let let_values: Vec<ast::Stmt> = (0 .. fields)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let name = builder.id(format!("__field{}", i));
|
let name = builder.id(format!("__field{}", i));
|
||||||
quote_stmt!(cx,
|
quote_stmt!(cx,
|
||||||
@@ -427,7 +427,7 @@ fn deserialize_struct_as_seq(
|
|||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
fields: &[ast::StructField],
|
fields: &[ast::StructField],
|
||||||
) -> Result<P<ast::Expr>, ()> {
|
) -> Result<P<ast::Expr>, ()> {
|
||||||
let let_values: Vec<P<ast::Stmt>> = (0 .. fields.len())
|
let let_values: Vec<ast::Stmt> = (0 .. fields.len())
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let name = builder.id(format!("__field{}", i));
|
let name = builder.id(format!("__field{}", i));
|
||||||
quote_stmt!(cx,
|
quote_stmt!(cx,
|
||||||
@@ -558,7 +558,7 @@ fn deserialize_item_enum(
|
|||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
|
|
||||||
let variants_expr = builder.expr().addr_of().slice()
|
let variants_expr = builder.expr().ref_().slice()
|
||||||
.with_exprs(
|
.with_exprs(
|
||||||
enum_def.variants.iter()
|
enum_def.variants.iter()
|
||||||
.map(|variant| {
|
.map(|variant| {
|
||||||
@@ -574,8 +574,8 @@ fn deserialize_item_enum(
|
|||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let mut variant_arms = vec![];
|
let mut variant_arms = vec![];
|
||||||
for (i, variant) in enum_def.variants.iter().enumerate() {
|
for (i, variant) in enum_def.variants.iter().enumerate() {
|
||||||
let variant_name = builder.pat().enum_()
|
let variant_name = builder.pat().path()
|
||||||
.id("__Field").id(format!("__field{}", i)).build()
|
.id("__Field").id(format!("__field{}", i))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let expr = try!(deserialize_variant(
|
let expr = try!(deserialize_variant(
|
||||||
@@ -917,7 +917,7 @@ fn deserialize_field_visitor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.visit(__FieldVisitor::<D>{ phantom: PhantomData })
|
deserializer.visit_struct_field(__FieldVisitor::<D>{ phantom: PhantomData })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
@@ -930,7 +930,7 @@ fn deserialize_struct_visitor(
|
|||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
fields: &[ast::StructField],
|
fields: &[ast::StructField],
|
||||||
) -> Result<(Vec<P<ast::Item>>, P<ast::Stmt>, P<ast::Expr>), ()> {
|
) -> Result<(Vec<P<ast::Item>>, ast::Stmt, P<ast::Expr>), ()> {
|
||||||
let field_visitor = deserialize_field_visitor(
|
let field_visitor = deserialize_field_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -944,7 +944,7 @@ fn deserialize_struct_visitor(
|
|||||||
fields,
|
fields,
|
||||||
));
|
));
|
||||||
|
|
||||||
let fields_expr = builder.expr().addr_of().slice()
|
let fields_expr = builder.expr().ref_().slice()
|
||||||
.with_exprs(
|
.with_exprs(
|
||||||
fields.iter()
|
fields.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
@@ -977,7 +977,7 @@ fn deserialize_map(
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Declare each field.
|
// Declare each field.
|
||||||
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
|
let let_values: Vec<ast::Stmt> = field_names.iter()
|
||||||
.map(|field_name| quote_stmt!(cx, let mut $field_name = None;).unwrap())
|
.map(|field_name| quote_stmt!(cx, let mut $field_name = None;).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@@ -994,7 +994,7 @@ fn deserialize_map(
|
|||||||
|
|
||||||
let field_attrs = try!(field::struct_field_attrs(cx, builder, fields));
|
let field_attrs = try!(field::struct_field_attrs(cx, builder, fields));
|
||||||
|
|
||||||
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
|
let extract_values: Vec<ast::Stmt> = field_names.iter()
|
||||||
.zip(field_attrs.iter())
|
.zip(field_attrs.iter())
|
||||||
.map(|(field_name, field_attr)| {
|
.map(|(field_name, field_attr)| {
|
||||||
let missing_expr = if field_attr.use_default() {
|
let missing_expr = if field_attr.use_default() {
|
||||||
|
|||||||
+12
-11
@@ -1,5 +1,6 @@
|
|||||||
#![cfg_attr(feature = "nightly", plugin(clippy))]
|
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
|
||||||
#![cfg_attr(feature = "nightly", allow(used_underscore_binding))]
|
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
|
||||||
|
#![cfg_attr(feature = "nightly-testing", allow(used_underscore_binding))]
|
||||||
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
|
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
|
||||||
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
|
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
|
||||||
|
|
||||||
@@ -31,14 +32,6 @@ include!("lib.rs.in");
|
|||||||
pub fn register(reg: &mut syntex::Registry) {
|
pub fn register(reg: &mut syntex::Registry) {
|
||||||
use syntax::{ast, fold};
|
use syntax::{ast, fold};
|
||||||
|
|
||||||
reg.add_attr("feature(custom_derive)");
|
|
||||||
reg.add_attr("feature(custom_attribute)");
|
|
||||||
|
|
||||||
reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
|
|
||||||
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
|
|
||||||
|
|
||||||
reg.add_post_expansion_pass(strip_attributes);
|
|
||||||
|
|
||||||
/// Strip the serde attributes from the crate.
|
/// Strip the serde attributes from the crate.
|
||||||
#[cfg(feature = "with-syntex")]
|
#[cfg(feature = "with-syntex")]
|
||||||
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
|
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
|
||||||
@@ -48,7 +41,7 @@ pub fn register(reg: &mut syntex::Registry) {
|
|||||||
impl fold::Folder for StripAttributeFolder {
|
impl fold::Folder for StripAttributeFolder {
|
||||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||||
match attr.node.value.node {
|
match attr.node.value.node {
|
||||||
ast::MetaList(ref n, _) if n == &"serde" => { return None; }
|
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +55,14 @@ pub fn register(reg: &mut syntex::Registry) {
|
|||||||
|
|
||||||
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
|
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg.add_attr("feature(custom_derive)");
|
||||||
|
reg.add_attr("feature(custom_attribute)");
|
||||||
|
|
||||||
|
reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
|
||||||
|
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
|
||||||
|
|
||||||
|
reg.add_post_expansion_pass(strip_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
#[cfg(not(feature = "with-syntex"))]
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ pub fn expand_derive_serialize(
|
|||||||
let builder = aster::AstBuilder::new().span(span);
|
let builder = aster::AstBuilder::new().span(span);
|
||||||
|
|
||||||
let generics = match item.node {
|
let generics = match item.node {
|
||||||
ast::ItemStruct(_, ref generics) => generics,
|
ast::ItemKind::Struct(_, ref generics) => generics,
|
||||||
ast::ItemEnum(_, ref generics) => generics,
|
ast::ItemKind::Enum(_, ref generics) => generics,
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(
|
cx.span_err(
|
||||||
meta_item.span,
|
meta_item.span,
|
||||||
@@ -88,7 +88,7 @@ fn serialize_body(
|
|||||||
let _ = try!(field::container_attrs(cx, item));
|
let _ = try!(field::container_attrs(cx, item));
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemStruct(ref variant_data, _) => {
|
ast::ItemKind::Struct(ref variant_data, _) => {
|
||||||
serialize_item_struct(
|
serialize_item_struct(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -99,7 +99,7 @@ fn serialize_body(
|
|||||||
variant_data,
|
variant_data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::ItemEnum(ref enum_def, _) => {
|
ast::ItemKind::Enum(ref enum_def, _) => {
|
||||||
serialize_item_enum(
|
serialize_item_enum(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -313,8 +313,8 @@ fn serialize_variant(
|
|||||||
|
|
||||||
match variant.node.data {
|
match variant.node.data {
|
||||||
ast::VariantData::Unit(_) => {
|
ast::VariantData::Unit(_) => {
|
||||||
let pat = builder.pat().enum_()
|
let pat = builder.pat().path()
|
||||||
.id(type_ident).id(variant_ident).build()
|
.id(type_ident).id(variant_ident)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Ok(quote_arm!(cx,
|
Ok(quote_arm!(cx,
|
||||||
|
|||||||
+15
-4
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
version = "0.6.10"
|
version = "0.6.14"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
@@ -12,12 +12,23 @@ keywords = ["serde", "serialization"]
|
|||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
plugin = true
|
plugin = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = "^0.0.36"
|
clippy = { version = "^0.*", optional = true }
|
||||||
serde_codegen = { version = "^0.6.10", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
serde_codegen = { version = "^0.6.14", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
compiletest_rs = "^0.0.11"
|
compiletest_rs = "^0.0.11"
|
||||||
num = "^0.1.27"
|
num = "^0.1.27"
|
||||||
rustc-serialize = "^0.3.16"
|
rustc-serialize = "^0.3.16"
|
||||||
serde = { version = "^0.6.10", path = "../serde", features = ["nightly", "num-impls"] }
|
serde = { version = "^0.6.14", path = "../serde", features = ["num-impls"] }
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "test"
|
||||||
|
path = "tests/test.rs"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "bench"
|
||||||
|
path = "benches/bench.rs"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![feature(custom_attribute, custom_derive, plugin, test)]
|
#![feature(custom_attribute, custom_derive, plugin, test)]
|
||||||
#![plugin(clippy)]
|
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate num;
|
extern crate num;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![feature(plugin, plugin_registrar, rustc_private)]
|
#![feature(plugin_registrar, rustc_private)]
|
||||||
#![plugin(clippy)]
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||||
|
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||||
|
|
||||||
extern crate serde_codegen;
|
extern crate serde_codegen;
|
||||||
extern crate rustc_plugin;
|
extern crate rustc_plugin;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_tests"
|
name = "serde_tests"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -11,21 +11,21 @@ keywords = ["serialization"]
|
|||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
nightly = ["clippy", "serde/nightly"]
|
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
syntex = { version = "^0.26.0" }
|
syntex = { version = "^0.29.0" }
|
||||||
syntex_syntax = { version = "^0.26.0" }
|
syntex_syntax = { version = "^0.29.0" }
|
||||||
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
|
serde_codegen = { version = "^0.6.14", path = "../serde_codegen", features = ["with-syntex"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
num = "^0.1.27"
|
num = "^0.1.26"
|
||||||
rustc-serialize = "^0.3.16"
|
rustc-serialize = "^0.3.16"
|
||||||
serde = { version = "*", path = "../serde", features = ["num-impls"] }
|
serde = { version = "*", path = "../serde", features = ["num-impls"] }
|
||||||
syntex = "^0.26.0"
|
syntex = "^0.29.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.0.36", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "test"
|
name = "test"
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ fn bench_decoder_000(b: &mut Bencher) {
|
|||||||
fn bench_decoder_003(b: &mut Bencher) {
|
fn bench_decoder_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in (0 .. 3) {
|
for i in 0 .. 3 {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||||
@@ -410,7 +410,7 @@ fn bench_decoder_003(b: &mut Bencher) {
|
|||||||
fn bench_decoder_100(b: &mut Bencher) {
|
fn bench_decoder_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in (0 .. 100) {
|
for i in 0 .. 100 {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||||
@@ -439,7 +439,7 @@ fn bench_deserializer_000(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_003(b: &mut Bencher) {
|
fn bench_deserializer_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in (0 .. 3) {
|
for i in 0 .. 3 {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||||
@@ -450,7 +450,7 @@ fn bench_deserializer_003(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_100(b: &mut Bencher) {
|
fn bench_deserializer_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in (0 .. 100) {
|
for i in 0 .. 100 {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use num::FromPrimitive;
|
use num::FromPrimitive;
|
||||||
use num::bigint::{BigInt, BigUint};
|
use num::bigint::{BigInt, BigUint};
|
||||||
@@ -589,4 +590,9 @@ declare_tests! {
|
|||||||
Token::SeqEnd,
|
Token::SeqEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_path_buf {
|
||||||
|
PathBuf::from("/usr/local/lib") => vec![
|
||||||
|
Token::String("/usr/local/lib".to_owned()),
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use num::FromPrimitive;
|
use num::FromPrimitive;
|
||||||
use num::bigint::{BigInt, BigUint};
|
use num::bigint::{BigInt, BigUint};
|
||||||
@@ -293,4 +294,14 @@ declare_ser_tests! {
|
|||||||
Token::SeqEnd,
|
Token::SeqEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_path {
|
||||||
|
Path::new("/usr/local/lib") => &[
|
||||||
|
Token::Str("/usr/local/lib"),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_path_buf {
|
||||||
|
PathBuf::from("/usr/local/lib") => &[
|
||||||
|
Token::Str("/usr/local/lib"),
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user