aboutsummaryrefslogtreecommitdiff
path: root/src/parse_assoc_type.rs
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-19 11:49:22 +0100
committerMartin Fischer <martin@push-f.com>2021-11-19 12:09:55 +0100
commit323762d238ebb9d9b8fa65bd1290aaa39648615c (patch)
treebba4645bf2fef6307018fe9187a19687149cbfbd /src/parse_assoc_type.rs
parenta11255acdf3b3fac12d8f51048f0bed2c0df8a11 (diff)
if first type bound isn't Into<T> auto-box it
Diffstat (limited to 'src/parse_assoc_type.rs')
-rw-r--r--src/parse_assoc_type.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/parse_assoc_type.rs b/src/parse_assoc_type.rs
index a255455..7efc7da 100644
--- a/src/parse_assoc_type.rs
+++ b/src/parse_assoc_type.rs
@@ -1,9 +1,10 @@
use proc_macro2::Span;
+use quote::{quote, ToTokens};
use syn::spanned::Spanned;
-use syn::{GenericArgument, Ident, PathArguments, PathSegment, TraitItemType, Type};
+use syn::{GenericArgument, Ident, Path, PathArguments, PathSegment, TraitItemType, Type};
use crate::parse_trait_sig::TypeTransform;
-use crate::syn_utils::{find_in_type, trait_bounds};
+use crate::syn_utils::{find_in_type, lifetime_bounds, trait_bounds};
use crate::AssocTypeMatcher;
#[derive(Debug)]
@@ -13,20 +14,39 @@ pub enum AssocTypeParseError {
NoIntoBound,
}
+#[derive(Debug, Clone)]
+pub struct BoxType {
+ trait_name: Path,
+ placeholder_lifetime: bool,
+}
+
+impl ToTokens for BoxType {
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+ let path = &self.trait_name;
+ match self.placeholder_lifetime {
+ true => tokens.extend(quote! {Box<dyn #path + '_>}),
+ false => tokens.extend(quote! {Box<dyn #path>}),
+ }
+ }
+}
+
pub enum DestType<'a> {
Into(&'a Type),
+ Box(BoxType),
}
impl DestType<'_> {
pub fn get_dest(&self) -> Type {
match self {
DestType::Into(ty) => (*ty).clone(),
+ DestType::Box(b) => Type::Verbatim(quote!(#b)),
}
}
pub fn type_transformation(&self) -> TypeTransform {
match self {
DestType::Into(_) => TypeTransform::Into,
+ DestType::Box(b) => TypeTransform::Box(b.clone()),
}
}
}
@@ -34,7 +54,7 @@ impl DestType<'_> {
pub fn parse_assoc_type(
assoc_type: &TraitItemType,
) -> Result<(&Ident, DestType), (Span, AssocTypeParseError)> {
- for bound in trait_bounds(&assoc_type.bounds) {
+ if let Some(bound) = trait_bounds(&assoc_type.bounds).next() {
if let PathSegment {
ident,
arguments: PathArguments::AngleBracketed(args),
@@ -59,6 +79,14 @@ pub fn parse_assoc_type(
}
}
}
+ return Ok((
+ &assoc_type.ident,
+ DestType::Box(BoxType {
+ trait_name: bound.path.clone(),
+ placeholder_lifetime: !lifetime_bounds(&assoc_type.bounds)
+ .any(|l| l.ident == "static"),
+ }),
+ ));
}
Err((assoc_type.span(), AssocTypeParseError::NoIntoBound))
}