Merge branch serde-rs/master into serde-rs/forward

This commit is contained in:
David Tolnay
2016-09-05 07:59:42 -07:00
14 changed files with 369 additions and 96 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# Serde   [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Coverage Status](https://coveralls.io/repos/serde-rs/serde/badge.svg?branch=master&service=github)](https://coveralls.io/github/serde-rs/serde?branch=master) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde) [![Clippy Linting Result](https://clippy.bashy.io/github/serde-rs/serde/master/badge.svg)](https://clippy.bashy.io/github/serde-rs/serde/master/log) # Serde   [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "0.8.4" version = "0.8.6"
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"
+186 -5
View File
@@ -709,6 +709,15 @@ impl<I, K, V, E> MapDeserializer<I, K, V, E>
marker: PhantomData, marker: PhantomData,
} }
} }
fn next(&mut self) -> Option<(K, V)> {
self.iter.next().map(|(k, v)| {
if let Some(len) = self.len.as_mut() {
*len -= 1;
}
(k, v)
})
}
} }
impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E> impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
@@ -725,10 +734,59 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
visitor.visit_map(self) visitor.visit_map(self)
} }
<<<<<<< HEAD
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any tuple_struct struct struct_field tuple enum ignored_any
||||||| merged common ancestors
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
=======
fn deserialize_seq<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Self::Error>
where V_: de::Visitor,
{
visitor.visit_seq(self)
}
fn deserialize_seq_fixed_size<V_>(&mut self, len: usize, mut visitor: V_) -> Result<V_::Value, Self::Error>
where V_: de::Visitor,
{
match self.len {
Some(map_len) if map_len == len => visitor.visit_seq(self),
Some(_) => Err(de::Error::invalid_length(len)),
None => visitor.visit_seq(self),
}
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
>>>>>>> origin/master
} }
} }
@@ -743,14 +801,11 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error> fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize, where T: de::Deserialize,
{ {
match self.iter.next() { match self.next() {
Some((key, value)) => { Some((key, value)) => {
if let Some(len) = self.len.as_mut() {
*len -= 1;
}
self.value = Some(value); self.value = Some(value);
let mut de = key.into_deserializer(); let mut de = key.into_deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut de)))) de::Deserialize::deserialize(&mut de).map(Some)
} }
None => Ok(None), None => Ok(None),
} }
@@ -784,6 +839,132 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
} }
} }
impl<I, K, V, E> de::SeqVisitor for MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
{
match self.next() {
Some(kv) => {
let mut de = PairDeserializer(Some(kv), PhantomData);
de::Deserialize::deserialize(&mut de).map(Some)
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Self::Error> {
de::MapVisitor::end(self)
}
fn size_hint(&self) -> (usize, Option<usize>) {
de::MapVisitor::size_hint(self)
}
}
// Used in the `impl SeqVisitor for MapDeserializer` to visit the map as a
// sequence of pairs.
struct PairDeserializer<A, B, E>(Option<(A, B)>, PhantomData<E>);
impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
where A: ValueDeserializer<E>,
B: ValueDeserializer<E>,
E: de::Error
{
type Error = E;
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit, deserialize_option,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct
}
fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
self.deserialize_seq(visitor)
}
fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
match self.0.take() {
Some((k, v)) => {
visitor.visit_seq(PairVisitor(Some(k), Some(v), PhantomData))
}
None => Err(de::Error::end_of_stream()),
}
}
fn deserialize_seq_fixed_size<V>(&mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
if len == 2 {
self.deserialize_seq(visitor)
} else {
Err(de::Error::invalid_length(len))
}
}
}
struct PairVisitor<A, B, E>(Option<A>, Option<B>, PhantomData<E>);
impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
where A: ValueDeserializer<E>,
B: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
{
if let Some(k) = self.0.take() {
let mut de = k.into_deserializer();
de::Deserialize::deserialize(&mut de).map(Some)
} else if let Some(v) = self.1.take() {
let mut de = v.into_deserializer();
de::Deserialize::deserialize(&mut de).map(Some)
} else {
Ok(None)
}
}
fn end(&mut self) -> Result<(), Self::Error> {
if self.1.is_none() {
Ok(())
} else {
Err(de::Error::invalid_length(self.size_hint().0))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = if self.0.is_some() {
2
} else if self.1.is_some() {
1
} else {
0
};
(len, Some(len))
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
+9 -9
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_codegen" name = "serde_codegen"
version = "0.8.4" version = "0.8.6"
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"
@@ -25,14 +25,14 @@ with-syntex = [
] ]
[build-dependencies] [build-dependencies]
quasi_codegen = { version = "^0.18.0", optional = true } quasi_codegen = { version = "^0.19.0", optional = true }
syntex = { version = "^0.42.2", optional = true } syntex = { version = "^0.43.0", optional = true }
[dependencies] [dependencies]
aster = { version = "^0.25.0", default-features = false } aster = { version = "^0.26.0", default-features = false }
clippy = { version = "^0.*", optional = true } clippy = { version = "^0.*", optional = true }
quasi = { version = "^0.18.0", default-features = false } quasi = { version = "^0.19.0", default-features = false }
quasi_macros = { version = "^0.18.0", optional = true } quasi_macros = { version = "^0.19.0", optional = true }
serde_codegen_internals = { version = "=0.7.0", default-features = false, path = "../serde_codegen_internals" } serde_codegen_internals = { version = "=0.8.0", default-features = false, path = "../serde_codegen_internals" }
syntex = { version = "^0.42.2", optional = true } syntex = { version = "^0.43.0", optional = true }
syntex_syntax = { version = "^0.42.0", optional = true } syntex_syntax = { version = "^0.43.0", optional = true }
+53 -37
View File
@@ -35,6 +35,58 @@ include!(concat!(env!("OUT_DIR"), "/lib.rs"));
#[cfg(not(feature = "with-syntex"))] #[cfg(not(feature = "with-syntex"))]
include!("lib.rs.in"); include!("lib.rs.in");
#[cfg(feature = "with-syntex")]
fn syntex_registry() -> syntex::Registry {
use syntax::{ast, fold};
/// Strip the serde attributes from the crate.
#[cfg(feature = "with-syntex")]
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
/// Helper folder that strips the serde attributes after the extensions have been expanded.
struct StripAttributeFolder;
impl fold::Folder for StripAttributeFolder {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
match attr.node.value.node {
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
_ => {}
}
Some(attr)
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
}
let mut reg = syntex::Registry::new();
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);
reg
}
#[cfg(feature = "with-syntex")]
pub fn expand_str(src: &str) -> Result<String, syntex::Error> {
let src = src.to_owned();
let expand_thread = move || {
syntex_registry().expand_str("", "", &src)
};
syntex::with_extra_stack(expand_thread)
}
#[cfg(feature = "with-syntex")] #[cfg(feature = "with-syntex")]
pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error> pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
where S: AsRef<Path>, where S: AsRef<Path>,
@@ -44,43 +96,7 @@ pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
let dst = dst.as_ref().to_owned(); let dst = dst.as_ref().to_owned();
let expand_thread = move || { let expand_thread = move || {
use syntax::{ast, fold}; syntex_registry().expand("", src, dst)
/// Strip the serde attributes from the crate.
#[cfg(feature = "with-syntex")]
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
/// Helper folder that strips the serde attributes after the extensions have been expanded.
struct StripAttributeFolder;
impl fold::Folder for StripAttributeFolder {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
match attr.node.value.node {
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
_ => {}
}
Some(attr)
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
}
let mut reg = syntex::Registry::new();
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);
reg.expand("", src, dst)
}; };
syntex::with_extra_stack(expand_thread) syntex::with_extra_stack(expand_thread)
+18 -14
View File
@@ -532,19 +532,21 @@ fn serialize_tuple_struct_visitor(
}; };
let skip = field.attrs.skip_serializing_if() let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr))) .map(|path| quote_expr!(cx, $path($field_expr)));
.unwrap_or(quote_expr!(cx, false));
if let Some(path) = field.attrs.serialize_with() { if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder, field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr); &structure_ty, generics, &field.ty, path, field_expr);
} }
quote_stmt!(cx, let ser = quote_expr!(cx,
if !$skip { try!(_serializer.$func(&mut state, $field_expr));
try!(_serializer.$func(&mut state, $field_expr)); );
}
).unwrap() match skip {
None => quote_stmt!(cx, $ser).unwrap(),
Some(skip) => quote_stmt!(cx, if !$skip { $ser }).unwrap(),
}
}) })
.collect() .collect()
} }
@@ -571,19 +573,21 @@ fn serialize_struct_visitor(
let key_expr = name_expr(builder, field.attrs.name()); let key_expr = name_expr(builder, field.attrs.name());
let skip = field.attrs.skip_serializing_if() let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr))) .map(|path| quote_expr!(cx, $path($field_expr)));
.unwrap_or(quote_expr!(cx, false));
if let Some(path) = field.attrs.serialize_with() { if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder, field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr) &structure_ty, generics, &field.ty, path, field_expr)
} }
quote_stmt!(cx, let ser = quote_expr!(cx,
if !$skip { try!(_serializer.$func(&mut state, $key_expr, $field_expr));
try!(_serializer.$func(&mut state, $key_expr, $field_expr)); );
}
).unwrap() match skip {
None => quote_stmt!(cx, $ser).unwrap(),
Some(skip) => quote_stmt!(cx, if !$skip { $ser }).unwrap(),
}
}) })
.collect() .collect()
} }
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_codegen_internals" name = "serde_codegen_internals"
version = "0.7.0" version = "0.8.0"
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 = "AST representation used by Serde codegen. Unstable." description = "AST representation used by Serde codegen. Unstable."
@@ -17,5 +17,5 @@ with-syntex = ["syntex_syntax", "syntex_errors"]
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } clippy = { version = "^0.*", optional = true }
syntex_syntax = { version = "^0.42.0", optional = true } syntex_syntax = { version = "^0.43.0", optional = true }
syntex_errors = { version = "^0.42.0", optional = true } syntex_errors = { version = "^0.43.0", optional = true }
+39 -19
View File
@@ -8,8 +8,7 @@ use syntax::fold::Folder;
use syntax::parse::parser::{Parser, PathStyle}; use syntax::parse::parser::{Parser, PathStyle};
use syntax::parse::token::{self, InternedString}; use syntax::parse::token::{self, InternedString};
use syntax::parse; use syntax::parse;
use syntax::print::pprust::{lit_to_string, meta_item_to_string}; use syntax::print::pprust::{lit_to_string, meta_item_to_string, meta_list_item_to_string};
use syntax::ptr::P;
use syntax::tokenstream::{self, TokenTree}; use syntax::tokenstream::{self, TokenTree};
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
@@ -165,7 +164,7 @@ impl Item {
cx.span_err( cx.span_err(
meta_item.span, meta_item.span,
&format!("unknown serde container attribute `{}`", &format!("unknown serde container attribute `{}`",
meta_item_to_string(meta_item))); meta_item_to_string(&meta_item)));
} }
} }
} }
@@ -236,7 +235,7 @@ impl Variant {
cx.span_err( cx.span_err(
meta_item.span, meta_item.span,
&format!("unknown serde variant attribute `{}`", &format!("unknown serde variant attribute `{}`",
meta_item_to_string(meta_item))); meta_item_to_string(&meta_item)));
} }
} }
} }
@@ -384,7 +383,7 @@ impl Field {
cx.span_err( cx.span_err(
meta_item.span, meta_item.span,
&format!("unknown serde field attribute `{}`", &format!("unknown serde field attribute `{}`",
meta_item_to_string(meta_item))); meta_item_to_string(&meta_item)));
} }
} }
} }
@@ -454,7 +453,7 @@ type SerAndDe<T> = (Option<Spanned<T>>, Option<Spanned<T>>);
fn get_ser_and_de<T, F>( fn get_ser_and_de<T, F>(
cx: &ExtCtxt, cx: &ExtCtxt,
attribute: &'static str, attribute: &'static str,
items: &[P<ast::MetaItem>], items: &[ast::NestedMetaItem],
f: F f: F
) -> Result<SerAndDe<T>, ()> ) -> Result<SerAndDe<T>, ()>
where F: Fn(&ExtCtxt, &str, &ast::Lit) -> Result<T, ()>, where F: Fn(&ExtCtxt, &str, &ast::Lit) -> Result<T, ()>,
@@ -464,15 +463,29 @@ fn get_ser_and_de<T, F>(
for item in items { for item in items {
match item.node { match item.node {
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"serialize" => { ast::NestedMetaItemKind::MetaItem(ref meta_item) => {
if let Ok(v) = f(cx, name, lit) { match meta_item.node {
ser_item.set(item.span, v); ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"serialize" => {
} if let Ok(v) = f(cx, name, lit) {
} ser_item.set(item.span, v);
}
}
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"deserialize" => { ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"deserialize" => {
if let Ok(v) = f(cx, name, lit) { if let Ok(v) = f(cx, name, lit) {
de_item.set(item.span, v); de_item.set(item.span, v);
}
}
_ => {
cx.span_err(
item.span,
&format!("unknown {} attribute `{}`",
attribute,
meta_item_to_string(meta_item)));
return Err(());
}
} }
} }
@@ -481,7 +494,7 @@ fn get_ser_and_de<T, F>(
item.span, item.span,
&format!("unknown {} attribute `{}`", &format!("unknown {} attribute `{}`",
attribute, attribute,
meta_item_to_string(item))); meta_list_item_to_string(item)));
return Err(()); return Err(());
} }
@@ -493,23 +506,30 @@ fn get_ser_and_de<T, F>(
fn get_renames( fn get_renames(
cx: &ExtCtxt, cx: &ExtCtxt,
items: &[P<ast::MetaItem>], items: &[ast::NestedMetaItem],
) -> Result<SerAndDe<InternedString>, ()> { ) -> Result<SerAndDe<InternedString>, ()> {
get_ser_and_de(cx, "rename", items, get_str_from_lit) get_ser_and_de(cx, "rename", items, get_str_from_lit)
} }
fn get_where_predicates( fn get_where_predicates(
cx: &ExtCtxt, cx: &ExtCtxt,
items: &[P<ast::MetaItem>], items: &[ast::NestedMetaItem],
) -> Result<SerAndDe<Vec<ast::WherePredicate>>, ()> { ) -> Result<SerAndDe<Vec<ast::WherePredicate>>, ()> {
get_ser_and_de(cx, "bound", items, parse_lit_into_where) get_ser_and_de(cx, "bound", items, parse_lit_into_where)
} }
pub fn get_serde_meta_items(attr: &ast::Attribute) -> Option<&[P<ast::MetaItem>]> { pub fn get_serde_meta_items(attr: &ast::Attribute) -> Option<Vec<ast::MetaItem>> {
match attr.node.value.node { match attr.node.value.node {
ast::MetaItemKind::List(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);
Some(items) Some(items.iter().filter_map(|item| {
match item.node {
ast::NestedMetaItemKind::MetaItem(ref meta_item) => {
Some((*meta_item.clone()).clone())
}
_ => None,
}
}).collect())
} }
_ => None _ => None
} }
+23
View File
@@ -0,0 +1,23 @@
[package]
name = "serde_derive"
version = "0.8.6"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/codegen.html"
keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[lib]
name = "serde_derive"
rustc-macro = true
[dependencies]
serde_codegen = { version = "=0.8.6", path = "../serde_codegen" }
[dev-dependencies]
fnv = "1.0"
serde = { version = "0.8.6", path = "../serde" }
serde_test = { version = "0.8.6", path = "../serde_test" }
+21
View File
@@ -0,0 +1,21 @@
#![feature(rustc_macro, rustc_macro_lib)]
#![cfg(not(test))]
extern crate rustc_macro;
extern crate serde_codegen;
use rustc_macro::TokenStream;
#[rustc_macro_derive(Serialize)]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let item = format!("#[derive(Serialize)]\n{}", input);
let expanded = serde_codegen::expand_str(&item).unwrap();
expanded.parse().unwrap()
}
#[rustc_macro_derive(Deserialize)]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let item = format!("#[derive(Deserialize)]\n{}", input);
let expanded = serde_codegen::expand_str(&item).unwrap();
expanded.parse().unwrap()
}
+8
View File
@@ -0,0 +1,8 @@
#![feature(test, rustc_macro, rustc_attrs)]
#[macro_use]
extern crate serde_derive;
extern crate test;
include!("../../testing/tests/test.rs.in");
+4 -4
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_macros" name = "serde_macros"
version = "0.8.4" version = "0.8.6"
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"
@@ -23,14 +23,14 @@ unstable-testing = [
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } clippy = { version = "^0.*", optional = true }
serde_codegen = { version = "=0.8.4", default-features = false, features = ["unstable"], path = "../serde_codegen" } serde_codegen = { version = "=0.8.6", default-features = false, features = ["unstable"], path = "../serde_codegen" }
[dev-dependencies] [dev-dependencies]
compiletest_rs = "^0.2.0" compiletest_rs = "^0.2.0"
fnv = "1.0" fnv = "1.0"
rustc-serialize = "^0.3.16" rustc-serialize = "^0.3.16"
serde = { version = "0.8.4", path = "../serde" } serde = { version = "0.8.6", path = "../serde" }
serde_test = { version = "0.8.4", path = "../serde_test" } serde_test = { version = "0.8.6", path = "../serde_test" }
[[test]] [[test]]
name = "test" name = "test"
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "0.8.4" version = "0.8.6"
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 = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
@@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"] include = ["Cargo.toml", "src/**/*.rs"]
[dependencies] [dependencies]
serde = { version = "0.8.4", path = "../serde" } serde = { version = "0.8.6", path = "../serde" }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_testing" name = "serde_testing"
version = "0.8.4" version = "0.8.6"
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"