elvwf

8 commits
Updated 2026-06-13 11:19:44
derive/src
derive/src/utils.rs
use proc_macro2::*;
use quote::*;
use syn::{visit_mut::*, *};

pub fn expr_strip(ty: &Type) -> TokenStream {
    let stripped = strip_lifetimes(ty);

    if let Type::Path(TypePath { qself: None, path }) = &stripped {
        let mut path = path.clone();

        for seg in path.segments.iter_mut() {
            if let PathArguments::AngleBracketed(args) = &mut seg.arguments {
                args.colon2_token = Some(syn::token::PathSep::default());
            }
        }

        quote!(#path)
    } else {
        quote!(#stripped)
    }
}

pub fn strip_lifetimes(ty: &Type) -> Type {
    let mut ty = ty.clone();
    StripLifetimes.visit_type_mut(&mut ty);
    ty
}

struct StripLifetimes;

impl VisitMut for StripLifetimes {
    fn visit_type_reference_mut(&mut self, node: &mut TypeReference) {
        node.lifetime = None;
        syn::visit_mut::visit_type_reference_mut(self, node);
    }

    fn visit_path_arguments_mut(&mut self, node: &mut PathArguments) {
        if let PathArguments::AngleBracketed(args) = node {
            let filtered: syn::punctuated::Punctuated<GenericArgument, Token![,]> = args
                .args
                .iter()
                .filter(|arg| !matches!(arg, GenericArgument::Lifetime(_)))
                .cloned()
                .collect();

            if filtered.is_empty() {
                *node = PathArguments::None;
                return;
            } else {
                args.args = filtered;
            }
        }
        syn::visit_mut::visit_path_arguments_mut(self, node);
    }
}