Use "bound" attribute instead of "where"
This commit is contained in:
parent
45c51d3198
commit
578f34ecaf
@ -62,8 +62,8 @@ impl Name {
|
||||
pub struct ContainerAttrs {
|
||||
name: Name,
|
||||
deny_unknown_fields: bool,
|
||||
ser_where: Option<Vec<ast::WherePredicate>>,
|
||||
de_where: Option<Vec<ast::WherePredicate>>,
|
||||
ser_bound: Option<Vec<ast::WherePredicate>>,
|
||||
de_bound: Option<Vec<ast::WherePredicate>>,
|
||||
}
|
||||
|
||||
impl ContainerAttrs {
|
||||
@ -72,8 +72,8 @@ impl ContainerAttrs {
|
||||
let mut container_attrs = ContainerAttrs {
|
||||
name: Name::new(item.ident),
|
||||
deny_unknown_fields: false,
|
||||
ser_where: None,
|
||||
de_where: None,
|
||||
ser_bound: None,
|
||||
de_bound: None,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Parse `#[serde(where="D: Serialize")]`
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"where" => {
|
||||
// Parse `#[serde(bound="D: Serialize")]`
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"bound" => {
|
||||
let where_predicates = try!(parse_lit_into_where(cx, name, lit));
|
||||
container_attrs.ser_where = Some(where_predicates.clone());
|
||||
container_attrs.de_where = Some(where_predicates.clone());
|
||||
container_attrs.ser_bound = Some(where_predicates.clone());
|
||||
container_attrs.de_bound = Some(where_predicates.clone());
|
||||
}
|
||||
|
||||
// Parse `#[serde(where(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"where" => {
|
||||
let (ser_where, de_where) = try!(get_where_predicates(cx, meta_items));
|
||||
container_attrs.ser_where = ser_where;
|
||||
container_attrs.de_where = de_where;
|
||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"bound" => {
|
||||
let (ser_bound, de_bound) = try!(get_where_predicates(cx, meta_items));
|
||||
container_attrs.ser_bound = ser_bound;
|
||||
container_attrs.de_bound = de_bound;
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -137,12 +137,12 @@ impl ContainerAttrs {
|
||||
self.deny_unknown_fields
|
||||
}
|
||||
|
||||
pub fn ser_where(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.ser_where.as_ref().map(|vec| &vec[..])
|
||||
pub fn ser_bound(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.ser_bound.as_ref().map(|vec| &vec[..])
|
||||
}
|
||||
|
||||
pub fn de_where(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.de_where.as_ref().map(|vec| &vec[..])
|
||||
pub fn de_bound(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.de_bound.as_ref().map(|vec| &vec[..])
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,8 +207,8 @@ pub struct FieldAttrs {
|
||||
default_expr_if_missing: Option<P<ast::Expr>>,
|
||||
serialize_with: Option<ast::Path>,
|
||||
deserialize_with: Option<ast::Path>,
|
||||
ser_where: Option<Vec<ast::WherePredicate>>,
|
||||
de_where: Option<Vec<ast::WherePredicate>>,
|
||||
ser_bound: Option<Vec<ast::WherePredicate>>,
|
||||
de_bound: Option<Vec<ast::WherePredicate>>,
|
||||
}
|
||||
|
||||
impl FieldAttrs {
|
||||
@ -231,8 +231,8 @@ impl FieldAttrs {
|
||||
default_expr_if_missing: None,
|
||||
serialize_with: None,
|
||||
deserialize_with: None,
|
||||
ser_where: None,
|
||||
de_where: None,
|
||||
ser_bound: None,
|
||||
de_bound: None,
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Parse `#[serde(where="D: Serialize")]`
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"where" => {
|
||||
// Parse `#[serde(bound="D: Serialize")]`
|
||||
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"bound" => {
|
||||
let where_predicates = try!(parse_lit_into_where(cx, name, lit));
|
||||
field_attrs.ser_where = Some(where_predicates.clone());
|
||||
field_attrs.de_where = Some(where_predicates.clone());
|
||||
field_attrs.ser_bound = Some(where_predicates.clone());
|
||||
field_attrs.de_bound = Some(where_predicates.clone());
|
||||
}
|
||||
|
||||
// Parse `#[serde(where(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"where" => {
|
||||
let (ser_where, de_where) = try!(get_where_predicates(cx, meta_items));
|
||||
field_attrs.ser_where = ser_where;
|
||||
field_attrs.de_where = de_where;
|
||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"bound" => {
|
||||
let (ser_bound, de_bound) = try!(get_where_predicates(cx, meta_items));
|
||||
field_attrs.ser_bound = ser_bound;
|
||||
field_attrs.de_bound = de_bound;
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -361,12 +361,12 @@ impl FieldAttrs {
|
||||
self.deserialize_with.as_ref()
|
||||
}
|
||||
|
||||
pub fn ser_where(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.ser_where.as_ref().map(|vec| &vec[..])
|
||||
pub fn ser_bound(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.ser_bound.as_ref().map(|vec| &vec[..])
|
||||
}
|
||||
|
||||
pub fn de_where(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.de_where.as_ref().map(|vec| &vec[..])
|
||||
pub fn de_bound(&self) -> Option<&[ast::WherePredicate]> {
|
||||
self.de_bound.as_ref().map(|vec| &vec[..])
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,7 +434,7 @@ fn get_where_predicates(
|
||||
cx: &ExtCtxt,
|
||||
items: &[P<ast::MetaItem>],
|
||||
) -> 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>]> {
|
||||
|
@ -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
|
||||
// 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.
|
||||
//
|
||||
// struct Test<D> {
|
||||
// #[serde(where="D: Serialize + Deserialize")]
|
||||
// #[serde(bound="D: Serialize + Deserialize")]
|
||||
// next: Box<Other<D>>,
|
||||
// }
|
||||
// struct Other<D> {
|
||||
// #[serde(where="D: Serialize + Deserialize")]
|
||||
// #[serde(bound="D: Serialize + Deserialize")]
|
||||
// next: Box<Test<D>>,
|
||||
// }
|
||||
fn contains_recursion(ty: &ast::Ty, ident: ast::Ident) -> bool {
|
||||
|
@ -111,16 +111,16 @@ fn build_impl_generics(
|
||||
|
||||
let generics = try!(bound::with_where_predicates_from_fields(
|
||||
cx, builder, item, &generics,
|
||||
|attrs| attrs.de_where()));
|
||||
|attrs| attrs.de_bound()));
|
||||
|
||||
match container_attrs.de_where() {
|
||||
match container_attrs.de_bound() {
|
||||
Some(predicates) => {
|
||||
let generics = bound::with_where_predicates(builder, &generics, predicates);
|
||||
Ok(generics)
|
||||
}
|
||||
None => {
|
||||
let generics = try!(bound::with_bound(cx, builder, item, &generics,
|
||||
deserialized_by_us,
|
||||
needs_deserialize_bound,
|
||||
&builder.path().ids(&["_serde", "de", "Deserialize"]).build()));
|
||||
let generics = try!(bound::with_bound(cx, builder, item, &generics,
|
||||
requires_default,
|
||||
@ -131,12 +131,13 @@ fn build_impl_generics(
|
||||
}
|
||||
|
||||
// Fields with a `skip_deserializing` or `deserialize_with` attribute are not
|
||||
// deserialized by us. All other fields may need a `T: Deserialize` bound where
|
||||
// T is the type of the field.
|
||||
fn deserialized_by_us(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
|
||||
// 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 {
|
||||
!attrs.skip_deserializing_field()
|
||||
&& 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
|
||||
|
@ -108,9 +108,9 @@ fn build_impl_generics(
|
||||
|
||||
let generics = try!(bound::with_where_predicates_from_fields(
|
||||
cx, builder, item, &generics,
|
||||
|attrs| attrs.ser_where()));
|
||||
|attrs| attrs.ser_bound()));
|
||||
|
||||
match container_attrs.ser_where() {
|
||||
match container_attrs.ser_bound() {
|
||||
Some(predicates) => {
|
||||
let generics = bound::with_where_predicates(builder, &generics, predicates);
|
||||
Ok(generics)
|
||||
@ -125,13 +125,13 @@ fn build_impl_generics(
|
||||
}
|
||||
|
||||
// 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
|
||||
// may need a `T: Serialize` bound where T is the type of the field.
|
||||
fn needs_serialize_bound(_: &ast::StructField, attrs: &attr::FieldAttrs) -> bool {
|
||||
!attrs.skip_serializing_field()
|
||||
&& attrs.serialize_with().is_none()
|
||||
&& attrs.ser_where().is_none()
|
||||
&& attrs.ser_bound().is_none()
|
||||
}
|
||||
|
||||
fn serialize_body(
|
||||
|
@ -92,19 +92,19 @@ struct ListNode<D> {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(where="D: SerializeWith + DeserializeWith")]
|
||||
#[serde(bound="D: SerializeWith + DeserializeWith")]
|
||||
struct WithTraits1<D, E> {
|
||||
#[serde(serialize_with="SerializeWith::serialize_with",
|
||||
deserialize_with="DeserializeWith::deserialize_with")]
|
||||
d: D,
|
||||
#[serde(serialize_with="SerializeWith::serialize_with",
|
||||
deserialize_with="DeserializeWith::deserialize_with",
|
||||
where="E: SerializeWith + DeserializeWith")]
|
||||
bound="E: SerializeWith + DeserializeWith")]
|
||||
e: E,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(where(serialize="D: SerializeWith",
|
||||
#[serde(bound(serialize="D: SerializeWith",
|
||||
deserialize="D: DeserializeWith"))]
|
||||
struct WithTraits2<D, E> {
|
||||
#[serde(serialize_with="SerializeWith::serialize_with",
|
||||
@ -112,7 +112,7 @@ struct WithTraits2<D, E> {
|
||||
d: D,
|
||||
#[serde(serialize_with="SerializeWith::serialize_with",
|
||||
deserialize_with="DeserializeWith::deserialize_with",
|
||||
where(serialize="E: SerializeWith",
|
||||
bound(serialize="E: SerializeWith",
|
||||
deserialize="E: DeserializeWith"))]
|
||||
e: E,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user