mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 10:38:02 +00:00
Merge branch 'v0.6.x' into master
# Conflicts: # serde/Cargo.toml # serde/src/ser/impls.rs # serde_codegen/src/attr.rs # serde_codegen/src/de.rs # serde_codegen/src/field.rs # serde_codegen/src/ser.rs
This commit is contained in:
+60
-31
@@ -4,6 +4,7 @@ use std::collections::HashSet;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::print::pprust::meta_item_to_string;
|
||||
use syntax::ptr::P;
|
||||
|
||||
use aster;
|
||||
@@ -32,7 +33,7 @@ impl FieldAttrs {
|
||||
/// Return a set of formats that the field has attributes for.
|
||||
pub fn formats(&self) -> HashSet<P<ast::Expr>> {
|
||||
match self.names {
|
||||
FieldNames::Format{ref formats, default: _} => {
|
||||
FieldNames::Format { ref formats, .. } => {
|
||||
let mut set = HashSet::new();
|
||||
for (fmt, _) in formats.iter() {
|
||||
set.insert(fmt.clone());
|
||||
@@ -70,7 +71,7 @@ impl FieldAttrs {
|
||||
pub fn default_key_expr(&self) -> &P<ast::Expr> {
|
||||
match self.names {
|
||||
FieldNames::Global(ref expr) => expr,
|
||||
FieldNames::Format{formats: _, ref default} => default,
|
||||
FieldNames::Format { ref default, .. } => default,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +105,7 @@ impl FieldAttrs {
|
||||
}
|
||||
|
||||
pub struct FieldAttrsBuilder<'a> {
|
||||
cx: &'a ExtCtxt<'a>,
|
||||
builder: &'a aster::AstBuilder,
|
||||
skip_serializing_field: bool,
|
||||
skip_serializing_field_if_empty: bool,
|
||||
@@ -114,8 +116,10 @@ pub struct FieldAttrsBuilder<'a> {
|
||||
}
|
||||
|
||||
impl<'a> FieldAttrsBuilder<'a> {
|
||||
pub fn new(builder: &'a aster::AstBuilder) -> FieldAttrsBuilder<'a> {
|
||||
pub fn new(cx: &'a ExtCtxt<'a>,
|
||||
builder: &'a aster::AstBuilder) -> FieldAttrsBuilder<'a> {
|
||||
FieldAttrsBuilder {
|
||||
cx: cx,
|
||||
builder: builder,
|
||||
skip_serializing_field: false,
|
||||
skip_serializing_field_if_empty: false,
|
||||
@@ -126,7 +130,7 @@ impl<'a> FieldAttrsBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn field(mut self, field: &ast::StructField) -> FieldAttrsBuilder<'a> {
|
||||
pub fn field(mut self, field: &ast::StructField) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||
match field.node.kind {
|
||||
ast::NamedField(name, _) => {
|
||||
self.name = Some(self.builder.expr().str(name));
|
||||
@@ -137,28 +141,36 @@ impl<'a> FieldAttrsBuilder<'a> {
|
||||
self.attrs(&field.node.attrs)
|
||||
}
|
||||
|
||||
pub fn attrs(self, attrs: &[ast::Attribute]) -> FieldAttrsBuilder<'a> {
|
||||
attrs.iter().fold(self, FieldAttrsBuilder::attr)
|
||||
pub fn attrs(mut self, attrs: &[ast::Attribute]) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||
for attr in attrs {
|
||||
self = try!(self.attr(attr));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn attr(self, attr: &ast::Attribute) -> FieldAttrsBuilder<'a> {
|
||||
pub fn attr(mut self, attr: &ast::Attribute) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaList(ref name, ref items) if name == &"serde" => {
|
||||
attr::mark_used(&attr);
|
||||
items.iter().fold(self, FieldAttrsBuilder::meta_item)
|
||||
for item in items {
|
||||
self = try!(self.meta_item(item));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
_ => {
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item(mut self, meta_item: &P<ast::MetaItem>) -> FieldAttrsBuilder<'a> {
|
||||
pub fn meta_item(mut self, meta_item: &P<ast::MetaItem>) -> Result<FieldAttrsBuilder<'a>, ()> {
|
||||
match meta_item.node {
|
||||
ast::MetaNameValue(ref name, ref lit) if name == &"rename" => {
|
||||
let expr = self.builder.expr().build_lit(P(lit.clone()));
|
||||
|
||||
self.name(expr)
|
||||
Ok(self.name(expr))
|
||||
}
|
||||
ast::MetaList(ref name, ref items) if name == &"rename" => {
|
||||
for item in items {
|
||||
@@ -172,23 +184,27 @@ impl<'a> FieldAttrsBuilder<'a> {
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
self
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
ast::MetaWord(ref name) if name == &"default" => {
|
||||
self.default()
|
||||
Ok(self.default())
|
||||
}
|
||||
ast::MetaWord(ref name) if name == &"skip_serializing" => {
|
||||
self.skip_serializing_field()
|
||||
Ok(self.skip_serializing_field())
|
||||
}
|
||||
ast::MetaWord(ref name) if name == &"skip_serializing_if_empty" => {
|
||||
self.skip_serializing_field_if_empty()
|
||||
Ok(self.skip_serializing_field_if_empty())
|
||||
}
|
||||
ast::MetaWord(ref name) if name == &"skip_serializing_if_none" => {
|
||||
self.skip_serializing_field_if_none()
|
||||
Ok(self.skip_serializing_field_if_none())
|
||||
}
|
||||
_ => {
|
||||
// Ignore unknown meta variables for now.
|
||||
self
|
||||
self.cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown serde field attribute `{}`",
|
||||
meta_item_to_string(meta_item)));
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,46 +272,59 @@ impl ContainerAttrs {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ContainerAttrsBuilder {
|
||||
pub struct ContainerAttrsBuilder<'a> {
|
||||
cx: &'a ExtCtxt<'a>,
|
||||
deny_unknown_fields: bool,
|
||||
}
|
||||
|
||||
impl ContainerAttrsBuilder {
|
||||
pub fn new() -> ContainerAttrsBuilder {
|
||||
impl<'a> ContainerAttrsBuilder<'a> {
|
||||
pub fn new(cx: &'a ExtCtxt) -> Self {
|
||||
ContainerAttrsBuilder {
|
||||
cx: cx,
|
||||
deny_unknown_fields: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attrs(self, attrs: &[ast::Attribute]) -> ContainerAttrsBuilder {
|
||||
attrs.iter().fold(self, ContainerAttrsBuilder::attr)
|
||||
pub fn attrs(mut self, attrs: &[ast::Attribute]) -> Result<Self, ()> {
|
||||
for attr in attrs {
|
||||
self = try!(self.attr(attr));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn attr(self, attr: &ast::Attribute) -> ContainerAttrsBuilder {
|
||||
pub fn attr(mut self, attr: &ast::Attribute) -> Result<Self, ()> {
|
||||
match attr.node.value.node {
|
||||
ast::MetaList(ref name, ref items) if name == &"serde" => {
|
||||
attr::mark_used(&attr);
|
||||
items.iter().fold(self, ContainerAttrsBuilder::meta_item)
|
||||
for item in items {
|
||||
self = try!(self.meta_item(item));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
_ => {
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_item(self, meta_item: &P<ast::MetaItem>) -> ContainerAttrsBuilder {
|
||||
pub fn meta_item(self, meta_item: &P<ast::MetaItem>) -> Result<Self, ()> {
|
||||
match meta_item.node {
|
||||
ast::MetaWord(ref name) if name == &"deny_unknown_fields" => {
|
||||
self.deny_unknown_fields()
|
||||
Ok(self.deny_unknown_fields())
|
||||
}
|
||||
_ => {
|
||||
// Ignore unknown meta variables for now.
|
||||
self
|
||||
self.cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown serde container attribute `{}`",
|
||||
meta_item_to_string(meta_item)));
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deny_unknown_fields(mut self) -> ContainerAttrsBuilder {
|
||||
pub fn deny_unknown_fields(mut self) -> Self {
|
||||
self.deny_unknown_fields = true;
|
||||
self
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user