sark-gen 0.11.0

Sark proc-macro generators
Documentation
use quote::format_ident;
use syn::visit::Visit;
use syn::visit_mut::VisitMut;

pub(super) struct TypeLifetimes<'a> {
    ty: &'a syn::Type,
}

impl<'a> TypeLifetimes<'a> {
    pub(super) fn new(ty: &'a syn::Type) -> Self {
        Self { ty }
    }

    pub(super) fn any(&self) -> bool {
        let mut detector = AnyLifetime(false);
        detector.visit_type(self.ty);
        detector.0
    }

    pub(super) fn has_non_static(&self) -> bool {
        let mut detector = NonStaticLifetime(false);
        detector.visit_type(self.ty);
        detector.0
    }

    pub(super) fn normalized_to(&self, ident: &str) -> syn::Type {
        let mut ty = self.ty.clone();
        LifetimeRenamer(ident).visit_type_mut(&mut ty);
        ty
    }
}

struct AnyLifetime(bool);

impl<'ast> Visit<'ast> for AnyLifetime {
    fn visit_lifetime(&mut self, _lifetime: &'ast syn::Lifetime) {
        self.0 = true;
    }
}

struct NonStaticLifetime(bool);

impl<'ast> Visit<'ast> for NonStaticLifetime {
    fn visit_lifetime(&mut self, lifetime: &'ast syn::Lifetime) {
        self.0 |= lifetime.ident != "static";
    }

    fn visit_type_reference(&mut self, reference: &'ast syn::TypeReference) {
        self.0 |= reference
            .lifetime
            .as_ref()
            .is_none_or(|lifetime| lifetime.ident != "static");
        syn::visit::visit_type_reference(self, reference);
    }
}

struct LifetimeRenamer<'a>(&'a str);

impl VisitMut for LifetimeRenamer<'_> {
    fn visit_lifetime_mut(&mut self, lifetime: &mut syn::Lifetime) {
        lifetime.ident = format_ident!("{}", self.0);
    }
}