Add partially-working where bounds for associated types

This commit is contained in:
Osspial
2018-04-09 23:22:18 -04:00
parent 5efb22ebee
commit c413775574
3 changed files with 21 additions and 8 deletions
+14 -3
View File
@@ -50,18 +50,29 @@ pub fn with_where_predicates(
generics generics
} }
pub fn with_where_predicates_from_fields<F>( pub fn with_where_predicates_from_fields<F, W>(
cont: &Container, cont: &Container,
generics: &syn::Generics, generics: &syn::Generics,
trait_bound: &syn::Path,
from_field: F, from_field: F,
where_ty: W,
) -> syn::Generics ) -> syn::Generics
where where
F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>, F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
W: for<'a> Fn(&attr::Field) -> Option<&syn::ExprPath>,
{ {
let predicates = cont.data let predicates = cont.data
.all_fields() .all_fields()
.flat_map(|field| from_field(&field.attrs)) .flat_map(|field| {
.flat_map(|predicates| predicates.to_vec()); let field_bound: Option<syn::WherePredicate> = match where_ty(&field.attrs) {
Some(_) => None,
None => {
let field_ty = field.ty;
Some(parse_quote!(#field_ty: #trait_bound))
}
};
field_bound.into_iter().chain(from_field(&field.attrs).into_iter().flat_map(|predicates| predicates.to_vec()))
});
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.make_where_clause() generics.make_where_clause()
+4 -3
View File
@@ -124,7 +124,9 @@ impl Parameters {
fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics { fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics {
let generics = bound::without_defaults(cont.generics); let generics = bound::without_defaults(cont.generics);
let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound); let delife = borrowed.de_lifetime();
let de_bound = parse_quote!(_serde::Deserialize<#delife>);
let generics = bound::with_where_predicates_from_fields(cont, &generics, &de_bound, attr::Field::de_bound, attr::Field::deserialize_with);
match cont.attrs.de_bound() { match cont.attrs.de_bound() {
Some(predicates) => bound::with_where_predicates(&generics, predicates), Some(predicates) => bound::with_where_predicates(&generics, predicates),
@@ -136,12 +138,11 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
attr::Default::None | attr::Default::Path(_) => generics, attr::Default::None | attr::Default::Path(_) => generics,
}; };
let delife = borrowed.de_lifetime();
let generics = bound::with_bound( let generics = bound::with_bound(
cont, cont,
&generics, &generics,
needs_deserialize_bound, needs_deserialize_bound,
&parse_quote!(_serde::Deserialize<#delife>), &de_bound,
); );
bound::with_bound( bound::with_bound(
+3 -2
View File
@@ -130,8 +130,9 @@ impl Parameters {
fn build_generics(cont: &Container) -> syn::Generics { fn build_generics(cont: &Container) -> syn::Generics {
let generics = bound::without_defaults(cont.generics); let generics = bound::without_defaults(cont.generics);
let trait_bound = parse_quote!(_serde::Serialize);
let generics = let generics =
bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound); bound::with_where_predicates_from_fields(cont, &generics, &trait_bound, attr::Field::ser_bound, attr::Field::serialize_with);
match cont.attrs.ser_bound() { match cont.attrs.ser_bound() {
Some(predicates) => bound::with_where_predicates(&generics, predicates), Some(predicates) => bound::with_where_predicates(&generics, predicates),
@@ -139,7 +140,7 @@ fn build_generics(cont: &Container) -> syn::Generics {
cont, cont,
&generics, &generics,
needs_serialize_bound, needs_serialize_bound,
&parse_quote!(_serde::Serialize), &trait_bound
), ),
} }
} }