mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-22 22:58:02 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a09f05644 | |||
| 5923a0cd2f | |||
| 1576b5a8a0 | |||
| 2c4dbf5a84 | |||
| 021f4f2d70 | |||
| decc571988 | |||
| 322d7a90db | |||
| dd3f653103 | |||
| 46a1860601 | |||
| 84a573c926 | |||
| 7dfa8f43f4 | |||
| 7375b4e847 | |||
| 48da62ed07 | |||
| 9834af7ed9 | |||
| 6b404d8529 | |||
| 3119cc8857 |
+4
-3
@@ -3,7 +3,8 @@ rust:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
- 1.5.0
|
||||
- 1.7.0
|
||||
- 1.8.0
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
@@ -18,7 +19,7 @@ script:
|
||||
- (cd serde && travis-cargo build)
|
||||
- (cd serde && travis-cargo test)
|
||||
- (cd serde && travis-cargo --only nightly test -- --features nightly-testing)
|
||||
- (cd serde && travis-cargo --skip 1.5.0 build -- --no-default-features)
|
||||
- (cd serde && travis-cargo build -- --no-default-features)
|
||||
- (cd serde && travis-cargo --only nightly build -- --no-default-features)
|
||||
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
|
||||
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features collections)
|
||||
@@ -26,7 +27,7 @@ script:
|
||||
- (cd serde_tests && travis-cargo --only nightly test -- --features nightly-testing)
|
||||
- (cd serde_macros && travis-cargo --only nightly test -- --features nightly-testing)
|
||||
- (cd serde_macros && travis-cargo --only nightly bench -- --features nightly-testing)
|
||||
- (cd examples/serde-syntex-example && travis-cargo --skip 1.5.0 run)
|
||||
- (cd examples/serde-syntex-example && travis-cargo run)
|
||||
- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --features nightly --no-default-features)
|
||||
- (cd serde && travis-cargo --only stable doc)
|
||||
- (cd serde_codegen && travis-cargo --only stable doc)
|
||||
|
||||
@@ -9,10 +9,10 @@ default = ["serde_codegen"]
|
||||
nightly = ["serde_macros"]
|
||||
|
||||
[build-dependencies]
|
||||
serde_codegen = { version = "^0.7.9", optional = true }
|
||||
serde_codegen = { version = "^0.7.10", optional = true }
|
||||
syntex = "^0.33.0"
|
||||
|
||||
[dependencies]
|
||||
serde = "^0.7.9"
|
||||
serde = "^0.7.10"
|
||||
serde_json = "^0.7.0"
|
||||
serde_macros = { version = "^0.7.9", optional = true }
|
||||
serde_macros = { version = "^0.7.10", optional = true }
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
|
||||
+46
-54
@@ -32,7 +32,7 @@ use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(all(feature = "nightly", feature = "collections"))]
|
||||
use collections::borrow::ToOwned;
|
||||
|
||||
use core::hash::Hash;
|
||||
use core::hash::{Hash, BuildHasher};
|
||||
use core::marker::PhantomData;
|
||||
#[cfg(feature = "std")]
|
||||
use std::net;
|
||||
@@ -381,29 +381,30 @@ impl<T> Deserialize for PhantomData<T> where T: Deserialize {
|
||||
macro_rules! seq_impl {
|
||||
(
|
||||
$ty:ty,
|
||||
< $($constraints:ident),* >,
|
||||
$visitor_name:ident,
|
||||
$visitor_ty:ident < $($typaram:ident : $bound1:ident $(+ $bound2:ident)*),* >,
|
||||
$visitor:ident,
|
||||
$ctor:expr,
|
||||
$with_capacity:expr,
|
||||
$insert:expr
|
||||
) => {
|
||||
/// A visitor that produces a sequence.
|
||||
pub struct $visitor_name<T> {
|
||||
marker: PhantomData<T>,
|
||||
pub struct $visitor_ty<$($typaram),*> {
|
||||
marker: PhantomData<$ty>,
|
||||
}
|
||||
|
||||
impl<T> $visitor_name<T> {
|
||||
impl<$($typaram),*> $visitor_ty<$($typaram),*>
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
/// Construct a new sequence visitor.
|
||||
pub fn new() -> Self {
|
||||
$visitor_name {
|
||||
$visitor_ty {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for $visitor_name<T>
|
||||
where T: $($constraints +)*,
|
||||
impl<$($typaram),*> Visitor for $visitor_ty<$($typaram),*>
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
@@ -430,13 +431,13 @@ macro_rules! seq_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deserialize for $ty
|
||||
where T: $($constraints +)*,
|
||||
impl<$($typaram),*> Deserialize for $ty
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.deserialize_seq($visitor_name::new())
|
||||
deserializer.deserialize_seq($visitor_ty::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,8 +446,7 @@ macro_rules! seq_impl {
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
seq_impl!(
|
||||
BinaryHeap<T>,
|
||||
<Deserialize, Ord>,
|
||||
BinaryHeapVisitor,
|
||||
BinaryHeapVisitor<T: Deserialize + Ord>,
|
||||
visitor,
|
||||
BinaryHeap::new(),
|
||||
BinaryHeap::with_capacity(visitor.size_hint().0),
|
||||
@@ -455,8 +455,7 @@ seq_impl!(
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
seq_impl!(
|
||||
BTreeSet<T>,
|
||||
<Deserialize, Eq, Ord>,
|
||||
BTreeSetVisitor,
|
||||
BTreeSetVisitor<T: Deserialize + Eq + Ord>,
|
||||
visitor,
|
||||
BTreeSet::new(),
|
||||
BTreeSet::new(),
|
||||
@@ -465,8 +464,7 @@ seq_impl!(
|
||||
#[cfg(all(feature = "nightly", feature = "collections"))]
|
||||
seq_impl!(
|
||||
EnumSet<T>,
|
||||
<Deserialize, CLike>,
|
||||
EnumSetVisitor,
|
||||
EnumSetVisitor<T: Deserialize + CLike>,
|
||||
visitor,
|
||||
EnumSet::new(),
|
||||
EnumSet::new(),
|
||||
@@ -475,8 +473,7 @@ seq_impl!(
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
seq_impl!(
|
||||
LinkedList<T>,
|
||||
<Deserialize>,
|
||||
LinkedListVisitor,
|
||||
LinkedListVisitor<T: Deserialize>,
|
||||
visitor,
|
||||
LinkedList::new(),
|
||||
LinkedList::new(),
|
||||
@@ -484,19 +481,18 @@ seq_impl!(
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
seq_impl!(
|
||||
HashSet<T>,
|
||||
<Deserialize, Eq, Hash>,
|
||||
HashSetVisitor,
|
||||
HashSet<T, S>,
|
||||
HashSetVisitor<T: Deserialize + Eq + Hash,
|
||||
S: BuildHasher + Default>,
|
||||
visitor,
|
||||
HashSet::new(),
|
||||
HashSet::with_capacity(visitor.size_hint().0),
|
||||
HashSet::with_hasher(S::default()),
|
||||
HashSet::with_capacity_and_hasher(visitor.size_hint().0, S::default()),
|
||||
HashSet::insert);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
seq_impl!(
|
||||
Vec<T>,
|
||||
<Deserialize>,
|
||||
VecVisitor,
|
||||
VecVisitor<T: Deserialize>,
|
||||
visitor,
|
||||
Vec::new(),
|
||||
Vec::with_capacity(visitor.size_hint().0),
|
||||
@@ -505,8 +501,7 @@ seq_impl!(
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
seq_impl!(
|
||||
VecDeque<T>,
|
||||
<Deserialize>,
|
||||
VecDequeVisitor,
|
||||
VecDequeVisitor<T: Deserialize>,
|
||||
visitor,
|
||||
VecDeque::new(),
|
||||
VecDeque::with_capacity(visitor.size_hint().0),
|
||||
@@ -726,30 +721,29 @@ tuple_impls! {
|
||||
macro_rules! map_impl {
|
||||
(
|
||||
$ty:ty,
|
||||
< $($constraints:ident),* >,
|
||||
$visitor_name:ident,
|
||||
$visitor_ty:ident < $($typaram:ident : $bound1:ident $(+ $bound2:ident)*),* >,
|
||||
$visitor:ident,
|
||||
$ctor:expr,
|
||||
$with_capacity:expr,
|
||||
$insert:expr
|
||||
$with_capacity:expr
|
||||
) => {
|
||||
/// A visitor that produces a map.
|
||||
pub struct $visitor_name<K, V> {
|
||||
pub struct $visitor_ty<$($typaram),*> {
|
||||
marker: PhantomData<$ty>,
|
||||
}
|
||||
|
||||
impl<K, V> $visitor_name<K, V> {
|
||||
impl<$($typaram),*> $visitor_ty<$($typaram),*>
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
/// Construct a `MapVisitor*<T>`.
|
||||
pub fn new() -> Self {
|
||||
$visitor_name {
|
||||
$visitor_ty {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Visitor for $visitor_name<K, V>
|
||||
where K: $($constraints +)*,
|
||||
V: Deserialize,
|
||||
impl<$($typaram),*> Visitor for $visitor_ty<$($typaram),*>
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
@@ -767,7 +761,7 @@ macro_rules! map_impl {
|
||||
let mut values = $with_capacity;
|
||||
|
||||
while let Some((key, value)) = try!($visitor.visit()) {
|
||||
$insert(&mut values, key, value);
|
||||
values.insert(key, value);
|
||||
}
|
||||
|
||||
try!($visitor.end());
|
||||
@@ -776,14 +770,13 @@ macro_rules! map_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Deserialize for $ty
|
||||
where K: $($constraints +)*,
|
||||
V: Deserialize,
|
||||
impl<$($typaram),*> Deserialize for $ty
|
||||
where $($typaram: $bound1 $(+ $bound2)*),*
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.deserialize_map($visitor_name::new())
|
||||
deserializer.deserialize_map($visitor_ty::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,22 +785,21 @@ macro_rules! map_impl {
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
map_impl!(
|
||||
BTreeMap<K, V>,
|
||||
<Deserialize, Eq, Ord>,
|
||||
BTreeMapVisitor,
|
||||
BTreeMapVisitor<K: Deserialize + Eq + Ord,
|
||||
V: Deserialize>,
|
||||
visitor,
|
||||
BTreeMap::new(),
|
||||
BTreeMap::new(),
|
||||
BTreeMap::insert);
|
||||
BTreeMap::new());
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
map_impl!(
|
||||
HashMap<K, V>,
|
||||
<Deserialize, Eq, Hash>,
|
||||
HashMapVisitor,
|
||||
HashMap<K, V, S>,
|
||||
HashMapVisitor<K: Deserialize + Eq + Hash,
|
||||
V: Deserialize,
|
||||
S: BuildHasher + Default>,
|
||||
visitor,
|
||||
HashMap::new(),
|
||||
HashMap::with_capacity(visitor.size_hint().0),
|
||||
HashMap::insert);
|
||||
HashMap::with_hasher(S::default()),
|
||||
HashMap::with_capacity_and_hasher(visitor.size_hint().0, S::default()));
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(all(feature = "nightly", feature = "collections"))]
|
||||
use collections::borrow::ToOwned;
|
||||
|
||||
use core::hash::Hash;
|
||||
use core::hash::{Hash, BuildHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
use core::iter;
|
||||
#[cfg(feature = "std")]
|
||||
@@ -330,8 +330,9 @@ impl<T> Serialize for EnumSet<T>
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T> Serialize for HashSet<T>
|
||||
impl<T, H> Serialize for HashSet<T, H>
|
||||
where T: Serialize + Eq + Hash,
|
||||
H: BuildHasher,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
@@ -651,9 +652,10 @@ impl<K, V> Serialize for BTreeMap<K, V>
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<K, V> Serialize for HashMap<K, V>
|
||||
impl<K, V, H> Serialize for HashMap<K, V, H>
|
||||
where K: Serialize + Eq + Hash,
|
||||
V: Serialize,
|
||||
H: BuildHasher,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_codegen"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
@@ -17,13 +17,13 @@ nightly-testing = ["clippy"]
|
||||
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
||||
|
||||
[build-dependencies]
|
||||
quasi_codegen = { version = "^0.11.0", optional = true }
|
||||
quasi_codegen = { version = "^0.12.0", optional = true }
|
||||
syntex = { version = "^0.33.0", optional = true }
|
||||
|
||||
[dependencies]
|
||||
aster = { version = "^0.17.0", default-features = false }
|
||||
aster = { version = "^0.18.0", default-features = false }
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
quasi = { version = "^0.11.0", default-features = false }
|
||||
quasi_macros = { version = "^0.11.0", optional = true }
|
||||
syntex = { version = "^0.33.0", optional = true }
|
||||
syntex_syntax = { version = "^0.33.0", optional = true }
|
||||
quasi = { version = "^0.12.0", default-features = false }
|
||||
quasi_macros = { version = "^0.12.0", optional = true }
|
||||
syntex = { version = "^0.35.0", optional = true }
|
||||
syntex_syntax = { version = "^0.35.0", optional = true }
|
||||
|
||||
@@ -8,13 +8,11 @@ mod inner {
|
||||
|
||||
pub fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let mut registry = syntex::Registry::new();
|
||||
quasi_codegen::register(&mut registry);
|
||||
|
||||
let src = Path::new("src/lib.rs.in");
|
||||
let dst = Path::new(&out_dir).join("lib.rs");
|
||||
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
quasi_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-22
@@ -212,13 +212,24 @@ pub struct FieldAttrs {
|
||||
skip_serializing_field: bool,
|
||||
skip_deserializing_field: bool,
|
||||
skip_serializing_if: Option<ast::Path>,
|
||||
default_expr_if_missing: Option<P<ast::Expr>>,
|
||||
default: FieldDefault,
|
||||
serialize_with: Option<ast::Path>,
|
||||
deserialize_with: Option<ast::Path>,
|
||||
ser_bound: Option<Vec<ast::WherePredicate>>,
|
||||
de_bound: Option<Vec<ast::WherePredicate>>,
|
||||
}
|
||||
|
||||
/// Represents the default to use for a field when deserializing.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum FieldDefault {
|
||||
/// Field must always be specified because it does not have a default.
|
||||
None,
|
||||
/// The default is given by `std::default::Default::default()`.
|
||||
Default,
|
||||
/// The default is given by this function.
|
||||
Path(ast::Path),
|
||||
}
|
||||
|
||||
impl FieldAttrs {
|
||||
/// Extract out the `#[serde(...)]` attributes from a struct field.
|
||||
pub fn from_field(cx: &ExtCtxt,
|
||||
@@ -236,7 +247,7 @@ impl FieldAttrs {
|
||||
skip_serializing_field: false,
|
||||
skip_deserializing_field: false,
|
||||
skip_serializing_if: None,
|
||||
default_expr_if_missing: None,
|
||||
default: FieldDefault::None,
|
||||
serialize_with: None,
|
||||
deserialize_with: None,
|
||||
ser_bound: None,
|
||||
@@ -266,17 +277,13 @@ impl FieldAttrs {
|
||||
|
||||
// Parse `#[serde(default)]`
|
||||
ast::MetaItemKind::Word(ref name) if name == &"default" => {
|
||||
let default_expr = builder.expr().default();
|
||||
field_attrs.default_expr_if_missing = Some(default_expr);
|
||||
field_attrs.default = FieldDefault::Default;
|
||||
}
|
||||
|
||||
// Parse `#[serde(default="...")]`
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"default" => {
|
||||
let wrapped_expr = wrap_default(
|
||||
try!(parse_lit_into_path(cx, name, lit)),
|
||||
);
|
||||
|
||||
field_attrs.default_expr_if_missing = Some(wrapped_expr);
|
||||
let path = try!(parse_lit_into_path(cx, name, lit));
|
||||
field_attrs.default = FieldDefault::Path(path);
|
||||
}
|
||||
|
||||
// Parse `#[serde(skip_serializing)]`
|
||||
@@ -290,9 +297,8 @@ impl FieldAttrs {
|
||||
|
||||
// Initialize field to Default::default() unless a different
|
||||
// default is specified by `#[serde(default="...")]`
|
||||
if field_attrs.default_expr_if_missing.is_none() {
|
||||
let default_expr = builder.expr().default();
|
||||
field_attrs.default_expr_if_missing = Some(default_expr);
|
||||
if field_attrs.default == FieldDefault::None {
|
||||
field_attrs.default = FieldDefault::Default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,8 +369,8 @@ impl FieldAttrs {
|
||||
self.skip_serializing_if.as_ref()
|
||||
}
|
||||
|
||||
pub fn default_expr_if_missing(&self) -> Option<&P<ast::Expr>> {
|
||||
self.default_expr_if_missing.as_ref()
|
||||
pub fn default(&self) -> &FieldDefault {
|
||||
&self.default
|
||||
}
|
||||
|
||||
pub fn serialize_with(&self) -> Option<&ast::Path> {
|
||||
@@ -584,11 +590,3 @@ fn parse_lit_into_where(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<Vec<
|
||||
Ok(where_clause.predicates)
|
||||
})
|
||||
}
|
||||
|
||||
/// This function wraps the expression in `#[serde(default="...")]` in a function to prevent it
|
||||
/// from accessing the internal `Deserialize` state.
|
||||
fn wrap_default(path: ast::Path) -> P<ast::Expr> {
|
||||
AstBuilder::new().expr().call()
|
||||
.build_path(path)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -60,13 +60,13 @@ pub fn with_bound<F>(
|
||||
filter: F,
|
||||
bound: &ast::Path,
|
||||
) -> Result<ast::Generics, Error>
|
||||
where F: Fn(&ast::StructField, &attr::FieldAttrs) -> bool,
|
||||
where F: Fn(&attr::FieldAttrs) -> bool,
|
||||
{
|
||||
Ok(builder.from_generics(generics.clone())
|
||||
.with_predicates(
|
||||
try!(all_fields_with_attrs(cx, item))
|
||||
.iter()
|
||||
.filter(|&&(ref field, ref attrs)| filter(field, attrs))
|
||||
.filter(|&&(_, ref attrs)| filter(attrs))
|
||||
.map(|&(ref field, _)| &field.ty)
|
||||
// TODO this filter can be removed later, see comment on function
|
||||
.filter(|ty| contains_generic(ty, generics))
|
||||
|
||||
+12
-18
@@ -134,7 +134,7 @@ fn build_impl_generics(
|
||||
// deserialized by us so we do not generate a bound. Fields with a `bound`
|
||||
// attribute specify their own bound so we do not generate one. All other fields
|
||||
// may need a `T: Deserialize` bound where T is the type of the field.
|
||||
fn needs_deserialize_bound(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
|
||||
fn needs_deserialize_bound(attrs: &attr::FieldAttrs) -> bool {
|
||||
!attrs.skip_deserializing_field()
|
||||
&& attrs.deserialize_with().is_none()
|
||||
&& attrs.de_bound().is_none()
|
||||
@@ -142,21 +142,8 @@ fn needs_deserialize_bound(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bo
|
||||
|
||||
// Fields with a `default` attribute (not `default=...`), and fields with a
|
||||
// `skip_deserializing` attribute that do not also have `default=...`.
|
||||
fn requires_default(field: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
|
||||
for meta_items in field.attrs.iter().filter_map(attr::get_serde_meta_items) {
|
||||
for meta_item in meta_items {
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::Word(ref name) if name == &"default" => {
|
||||
return true
|
||||
}
|
||||
ast::MetaItemKind::NameValue(ref name, _) if name == &"default" => {
|
||||
return false
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
attrs.skip_deserializing_field()
|
||||
fn requires_default(attrs: &attr::FieldAttrs) -> bool {
|
||||
attrs.default() == &attr::FieldDefault::Default
|
||||
}
|
||||
|
||||
fn deserialize_body(
|
||||
@@ -1234,9 +1221,16 @@ fn expr_is_missing(
|
||||
cx: &ExtCtxt,
|
||||
attrs: &attr::FieldAttrs,
|
||||
) -> P<ast::Expr> {
|
||||
if let Some(expr) = attrs.default_expr_if_missing() {
|
||||
return expr.clone();
|
||||
match *attrs.default() {
|
||||
attr::FieldDefault::Default => {
|
||||
return quote_expr!(cx, ::std::default::Default::default());
|
||||
}
|
||||
attr::FieldDefault::Path(ref path) => {
|
||||
return quote_expr!(cx, $path());
|
||||
}
|
||||
attr::FieldDefault::None => { /* below */ }
|
||||
}
|
||||
|
||||
let name = attrs.name().deserialize_name_expr();
|
||||
match attrs.deserialize_with() {
|
||||
None => {
|
||||
|
||||
@@ -128,7 +128,7 @@ fn build_impl_generics(
|
||||
// serialized by us so we do not generate a bound. Fields with a `bound`
|
||||
// attribute specify their own bound so we do not generate one. All other fields
|
||||
// may need a `T: Serialize` bound where T is the type of the field.
|
||||
fn needs_serialize_bound(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
|
||||
fn needs_serialize_bound(attrs: &attr::FieldAttrs) -> bool {
|
||||
!attrs.skip_serializing_field()
|
||||
&& attrs.serialize_with().is_none()
|
||||
&& attrs.ser_bound().is_none()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_macros"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
@@ -18,12 +18,13 @@ nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-tes
|
||||
|
||||
[dependencies]
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
serde_codegen = { version = "^0.7.9", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
||||
serde_codegen = { version = "^0.7.10", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
||||
|
||||
[dev-dependencies]
|
||||
compiletest_rs = "^0.1.1"
|
||||
fnv = "1.0"
|
||||
rustc-serialize = "^0.3.16"
|
||||
serde = { version = "^0.7.9", path = "../serde" }
|
||||
serde = { version = "^0.7.10", path = "../serde" }
|
||||
|
||||
[[test]]
|
||||
name = "test"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_tests"
|
||||
version = "0.7.9"
|
||||
version = "0.7.10"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
@@ -14,14 +14,15 @@ build = "build.rs"
|
||||
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
|
||||
|
||||
[build-dependencies]
|
||||
syntex = { version = "^0.33.0" }
|
||||
syntex_syntax = { version = "^0.33.0" }
|
||||
syntex = { version = "^0.35.0" }
|
||||
syntex_syntax = { version = "^0.35.0" }
|
||||
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
|
||||
|
||||
[dev-dependencies]
|
||||
fnv = "1.0"
|
||||
rustc-serialize = "^0.3.16"
|
||||
serde = { version = "*", path = "../serde" }
|
||||
syntex = "^0.33.0"
|
||||
syntex = "^0.35.0"
|
||||
|
||||
[dependencies]
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
|
||||
@@ -13,10 +13,6 @@ fn main() {
|
||||
] {
|
||||
let src = Path::new(src);
|
||||
let dst = Path::new(&out_dir).join(dst);
|
||||
|
||||
let mut registry = syntex::Registry::new();
|
||||
|
||||
serde_codegen::register(&mut registry);
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
serde_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,14 @@ macro_rules! hashset {
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}
|
||||
};
|
||||
($hasher:ident @ $($value:expr),+) => {
|
||||
{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,5 +83,13 @@ macro_rules! hashmap {
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}
|
||||
};
|
||||
($hasher:ident @ $($key:expr => $value:expr),+) => {
|
||||
{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::net;
|
||||
use std::path::PathBuf;
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
|
||||
use token::{
|
||||
Error,
|
||||
Token,
|
||||
@@ -284,6 +287,18 @@ declare_tests! {
|
||||
Token::TupleStructStart("Anything", Some(0)),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
hashset![FnvHasher @ 1, 2, 3] => vec![
|
||||
Token::SeqStart(Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::I32(3),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
}
|
||||
test_vec {
|
||||
Vec::<isize>::new() => vec![
|
||||
@@ -532,6 +547,17 @@ declare_tests! {
|
||||
Token::StructStart("Anything", Some(0)),
|
||||
Token::MapEnd,
|
||||
],
|
||||
hashmap![FnvHasher @ 1 => 2, 3 => 4] => vec![
|
||||
Token::MapStart(Some(2)),
|
||||
Token::MapSep,
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::I32(3),
|
||||
Token::I32(4),
|
||||
Token::MapEnd,
|
||||
],
|
||||
}
|
||||
test_struct {
|
||||
Struct { a: 1, b: 2, c: 0 } => vec![
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::net;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str;
|
||||
|
||||
use token::{self, Token};
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -144,6 +147,24 @@ declare_ser_tests! {
|
||||
Token::SeqEnd,
|
||||
],
|
||||
}
|
||||
test_hashset {
|
||||
HashSet::<isize>::new() => &[
|
||||
Token::SeqStart(Some(0)),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
hashset![1] => &[
|
||||
Token::SeqStart(Some(1)),
|
||||
Token::SeqSep,
|
||||
Token::I32(1),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
hashset![FnvHasher @ 1] => &[
|
||||
Token::SeqStart(Some(1)),
|
||||
Token::SeqSep,
|
||||
Token::I32(1),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
}
|
||||
test_tuple {
|
||||
(1,) => &[
|
||||
Token::TupleStart(1),
|
||||
@@ -204,6 +225,26 @@ declare_ser_tests! {
|
||||
Token::MapEnd,
|
||||
],
|
||||
}
|
||||
test_hashmap {
|
||||
HashMap::<isize, isize>::new() => &[
|
||||
Token::MapStart(Some(0)),
|
||||
Token::MapEnd,
|
||||
],
|
||||
hashmap![1 => 2] => &[
|
||||
Token::MapStart(Some(1)),
|
||||
Token::MapSep,
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::MapEnd,
|
||||
],
|
||||
hashmap![FnvHasher @ 1 => 2] => &[
|
||||
Token::MapStart(Some(1)),
|
||||
Token::MapSep,
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::MapEnd,
|
||||
],
|
||||
}
|
||||
test_unit_struct {
|
||||
UnitStruct => &[Token::UnitStruct("UnitStruct")],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user