mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 10:11:01 +00:00
Use "bound" attribute instead of "where"
This commit is contained in:
+35
-35
@@ -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>]> {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user