Use "bound" attribute instead of "where"

This commit is contained in:
David Tolnay
2016-06-05 10:47:40 -07:00
parent 45c51d3198
commit 578f34ecaf
5 changed files with 54 additions and 53 deletions
+35 -35
View File
@@ -62,8 +62,8 @@ impl Name {
pub struct ContainerAttrs { pub struct ContainerAttrs {
name: Name, name: Name,
deny_unknown_fields: bool, deny_unknown_fields: bool,
ser_where: Option<Vec<ast::WherePredicate>>, ser_bound: Option<Vec<ast::WherePredicate>>,
de_where: Option<Vec<ast::WherePredicate>>, de_bound: Option<Vec<ast::WherePredicate>>,
} }
impl ContainerAttrs { impl ContainerAttrs {
@@ -72,8 +72,8 @@ impl ContainerAttrs {
let mut container_attrs = ContainerAttrs { let mut container_attrs = ContainerAttrs {
name: Name::new(item.ident), name: Name::new(item.ident),
deny_unknown_fields: false, deny_unknown_fields: false,
ser_where: None, ser_bound: None,
de_where: None, de_bound: None,
}; };
for meta_items in item.attrs().iter().filter_map(get_serde_meta_items) { for meta_items in item.attrs().iter().filter_map(get_serde_meta_items) {
@@ -100,18 +100,18 @@ impl ContainerAttrs {
container_attrs.deny_unknown_fields = true; container_attrs.deny_unknown_fields = true;
} }
// Parse `#[serde(where="D: Serialize")]` // Parse `#[serde(bound="D: Serialize")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"where" => { ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"bound" => {
let where_predicates = try!(parse_lit_into_where(cx, name, lit)); let where_predicates = try!(parse_lit_into_where(cx, name, lit));
container_attrs.ser_where = Some(where_predicates.clone()); container_attrs.ser_bound = Some(where_predicates.clone());
container_attrs.de_where = Some(where_predicates.clone()); container_attrs.de_bound = Some(where_predicates.clone());
} }
// Parse `#[serde(where(serialize="D: Serialize", deserialize="D: Deserialize"))]` // Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"where" => { ast::MetaItemKind::List(ref name, ref meta_items) if name == &"bound" => {
let (ser_where, de_where) = try!(get_where_predicates(cx, meta_items)); let (ser_bound, de_bound) = try!(get_where_predicates(cx, meta_items));
container_attrs.ser_where = ser_where; container_attrs.ser_bound = ser_bound;
container_attrs.de_where = de_where; container_attrs.de_bound = de_bound;
} }
_ => { _ => {
@@ -137,12 +137,12 @@ impl ContainerAttrs {
self.deny_unknown_fields self.deny_unknown_fields
} }
pub fn ser_where(&self) -> Option<&[ast::WherePredicate]> { pub fn ser_bound(&self) -> Option<&[ast::WherePredicate]> {
self.ser_where.as_ref().map(|vec| &vec[..]) self.ser_bound.as_ref().map(|vec| &vec[..])
} }
pub fn de_where(&self) -> Option<&[ast::WherePredicate]> { pub fn de_bound(&self) -> Option<&[ast::WherePredicate]> {
self.de_where.as_ref().map(|vec| &vec[..]) self.de_bound.as_ref().map(|vec| &vec[..])
} }
} }
@@ -207,8 +207,8 @@ pub struct FieldAttrs {
default_expr_if_missing: Option<P<ast::Expr>>, default_expr_if_missing: Option<P<ast::Expr>>,
serialize_with: Option<ast::Path>, serialize_with: Option<ast::Path>,
deserialize_with: Option<ast::Path>, deserialize_with: Option<ast::Path>,
ser_where: Option<Vec<ast::WherePredicate>>, ser_bound: Option<Vec<ast::WherePredicate>>,
de_where: Option<Vec<ast::WherePredicate>>, de_bound: Option<Vec<ast::WherePredicate>>,
} }
impl FieldAttrs { impl FieldAttrs {
@@ -231,8 +231,8 @@ impl FieldAttrs {
default_expr_if_missing: None, default_expr_if_missing: None,
serialize_with: None, serialize_with: None,
deserialize_with: None, deserialize_with: None,
ser_where: None, ser_bound: None,
de_where: None, de_bound: None,
}; };
for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) { for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
@@ -304,18 +304,18 @@ impl FieldAttrs {
field_attrs.deserialize_with = Some(path); field_attrs.deserialize_with = Some(path);
} }
// Parse `#[serde(where="D: Serialize")]` // Parse `#[serde(bound="D: Serialize")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"where" => { ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"bound" => {
let where_predicates = try!(parse_lit_into_where(cx, name, lit)); let where_predicates = try!(parse_lit_into_where(cx, name, lit));
field_attrs.ser_where = Some(where_predicates.clone()); field_attrs.ser_bound = Some(where_predicates.clone());
field_attrs.de_where = Some(where_predicates.clone()); field_attrs.de_bound = Some(where_predicates.clone());
} }
// Parse `#[serde(where(serialize="D: Serialize", deserialize="D: Deserialize"))]` // Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"where" => { ast::MetaItemKind::List(ref name, ref meta_items) if name == &"bound" => {
let (ser_where, de_where) = try!(get_where_predicates(cx, meta_items)); let (ser_bound, de_bound) = try!(get_where_predicates(cx, meta_items));
field_attrs.ser_where = ser_where; field_attrs.ser_bound = ser_bound;
field_attrs.de_where = de_where; field_attrs.de_bound = de_bound;
} }
_ => { _ => {
@@ -361,12 +361,12 @@ impl FieldAttrs {
self.deserialize_with.as_ref() self.deserialize_with.as_ref()
} }
pub fn ser_where(&self) -> Option<&[ast::WherePredicate]> { pub fn ser_bound(&self) -> Option<&[ast::WherePredicate]> {
self.ser_where.as_ref().map(|vec| &vec[..]) self.ser_bound.as_ref().map(|vec| &vec[..])
} }
pub fn de_where(&self) -> Option<&[ast::WherePredicate]> { pub fn de_bound(&self) -> Option<&[ast::WherePredicate]> {
self.de_where.as_ref().map(|vec| &vec[..]) self.de_bound.as_ref().map(|vec| &vec[..])
} }
} }
@@ -434,7 +434,7 @@ fn get_where_predicates(
cx: &ExtCtxt, cx: &ExtCtxt,
items: &[P<ast::MetaItem>], items: &[P<ast::MetaItem>],
) -> Result<(Option<Vec<ast::WherePredicate>>, Option<Vec<ast::WherePredicate>>), Error> { ) -> Result<(Option<Vec<ast::WherePredicate>>, Option<Vec<ast::WherePredicate>>), Error> {
get_ser_and_de(cx, "where", 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<&[P<ast::MetaItem>]> {
+3 -3
View File
@@ -168,15 +168,15 @@ fn contains_generic(ty: &ast::Ty, generics: &ast::Generics) -> bool {
// } // }
// //
// This does not catch field types that are mutually recursive with some other // This does not catch field types that are mutually recursive with some other
// type. For those, we require bounds to be specified by a `where` attribute if // type. For those, we require bounds to be specified by a `bound` attribute if
// the inferred ones are not correct. // the inferred ones are not correct.
// //
// struct Test<D> { // struct Test<D> {
// #[serde(where="D: Serialize + Deserialize")] // #[serde(bound="D: Serialize + Deserialize")]
// next: Box<Other<D>>, // next: Box<Other<D>>,
// } // }
// struct Other<D> { // struct Other<D> {
// #[serde(where="D: Serialize + Deserialize")] // #[serde(bound="D: Serialize + Deserialize")]
// next: Box<Test<D>>, // next: Box<Test<D>>,
// } // }
fn contains_recursion(ty: &ast::Ty, ident: ast::Ident) -> bool { fn contains_recursion(ty: &ast::Ty, ident: ast::Ident) -> bool {
+8 -7
View File
@@ -111,16 +111,16 @@ fn build_impl_generics(
let generics = try!(bound::with_where_predicates_from_fields( let generics = try!(bound::with_where_predicates_from_fields(
cx, builder, item, &generics, cx, builder, item, &generics,
|attrs| attrs.de_where())); |attrs| attrs.de_bound()));
match container_attrs.de_where() { match container_attrs.de_bound() {
Some(predicates) => { Some(predicates) => {
let generics = bound::with_where_predicates(builder, &generics, predicates); let generics = bound::with_where_predicates(builder, &generics, predicates);
Ok(generics) Ok(generics)
} }
None => { None => {
let generics = try!(bound::with_bound(cx, builder, item, &generics, let generics = try!(bound::with_bound(cx, builder, item, &generics,
deserialized_by_us, needs_deserialize_bound,
&builder.path().ids(&["_serde", "de", "Deserialize"]).build())); &builder.path().ids(&["_serde", "de", "Deserialize"]).build()));
let generics = try!(bound::with_bound(cx, builder, item, &generics, let generics = try!(bound::with_bound(cx, builder, item, &generics,
requires_default, requires_default,
@@ -131,12 +131,13 @@ fn build_impl_generics(
} }
// Fields with a `skip_deserializing` or `deserialize_with` attribute are not // Fields with a `skip_deserializing` or `deserialize_with` attribute are not
// deserialized by us. All other fields may need a `T: Deserialize` bound where // deserialized by us so we do not generate a bound. Fields with a `bound`
// T is the type of the field. // attribute specify their own bound so we do not generate one. All other fields
fn deserialized_by_us(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool { // may need a `T: Deserialize` bound where T is the type of the field.
fn needs_deserialize_bound(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
!attrs.skip_deserializing_field() !attrs.skip_deserializing_field()
&& attrs.deserialize_with().is_none() && attrs.deserialize_with().is_none()
&& attrs.de_where().is_none() && attrs.de_bound().is_none()
} }
// Fields with a `default` attribute (not `default=...`), and fields with a // Fields with a `default` attribute (not `default=...`), and fields with a
+4 -4
View File
@@ -108,9 +108,9 @@ fn build_impl_generics(
let generics = try!(bound::with_where_predicates_from_fields( let generics = try!(bound::with_where_predicates_from_fields(
cx, builder, item, &generics, cx, builder, item, &generics,
|attrs| attrs.ser_where())); |attrs| attrs.ser_bound()));
match container_attrs.ser_where() { match container_attrs.ser_bound() {
Some(predicates) => { Some(predicates) => {
let generics = bound::with_where_predicates(builder, &generics, predicates); let generics = bound::with_where_predicates(builder, &generics, predicates);
Ok(generics) Ok(generics)
@@ -125,13 +125,13 @@ fn build_impl_generics(
} }
// Fields with a `skip_serializing` or `serialize_with` attribute are not // Fields with a `skip_serializing` or `serialize_with` attribute are not
// serialized by us so we do not generate a bound. Fields with a `where` // 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 // 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. // 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(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
!attrs.skip_serializing_field() !attrs.skip_serializing_field()
&& attrs.serialize_with().is_none() && attrs.serialize_with().is_none()
&& attrs.ser_where().is_none() && attrs.ser_bound().is_none()
} }
fn serialize_body( fn serialize_body(
+4 -4
View File
@@ -92,19 +92,19 @@ struct ListNode<D> {
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(where="D: SerializeWith + DeserializeWith")] #[serde(bound="D: SerializeWith + DeserializeWith")]
struct WithTraits1<D, E> { struct WithTraits1<D, E> {
#[serde(serialize_with="SerializeWith::serialize_with", #[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with")] deserialize_with="DeserializeWith::deserialize_with")]
d: D, d: D,
#[serde(serialize_with="SerializeWith::serialize_with", #[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with", deserialize_with="DeserializeWith::deserialize_with",
where="E: SerializeWith + DeserializeWith")] bound="E: SerializeWith + DeserializeWith")]
e: E, e: E,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(where(serialize="D: SerializeWith", #[serde(bound(serialize="D: SerializeWith",
deserialize="D: DeserializeWith"))] deserialize="D: DeserializeWith"))]
struct WithTraits2<D, E> { struct WithTraits2<D, E> {
#[serde(serialize_with="SerializeWith::serialize_with", #[serde(serialize_with="SerializeWith::serialize_with",
@@ -112,7 +112,7 @@ struct WithTraits2<D, E> {
d: D, d: D,
#[serde(serialize_with="SerializeWith::serialize_with", #[serde(serialize_with="SerializeWith::serialize_with",
deserialize_with="DeserializeWith::deserialize_with", deserialize_with="DeserializeWith::deserialize_with",
where(serialize="E: SerializeWith", bound(serialize="E: SerializeWith",
deserialize="E: DeserializeWith"))] deserialize="E: DeserializeWith"))]
e: E, e: E,
} }