use proc_macro2::Span;
use syn::ext::IdentExt as _;
use syn::{Ident, Lifetime, Type};
pub fn static_lt() -> Lifetime {
Lifetime::new("'static", Span::call_site())
}
pub fn custom_lt(s: &str) -> Lifetime {
Lifetime::new(s, Span::call_site())
}
pub fn ignored_lifetime_ident() -> Ident {
Ident::new("_does_not_matter", Span::call_site())
}
pub fn replace_lifetime(lt_param: &Ident, x: &Type, lt: Lifetime) -> Type {
use syn::fold::Fold;
struct ReplaceLifetime<'a>(&'a Ident, Lifetime);
impl Fold for ReplaceLifetime<'_> {
fn fold_lifetime(&mut self, lt: Lifetime) -> Lifetime {
if lt.ident.unraw() == *self.0 {
self.1.clone()
} else {
lt
}
}
}
ReplaceLifetime(lt_param, lt).fold_type(x.clone())
}
#[cfg(test)]
mod tests {
use proc_macro2::Span;
use syn::{parse_quote, Ident};
use super::{custom_lt, replace_lifetime};
fn a_ident() -> Ident {
Ident::new("a", Span::call_site())
}
fn b_ident() -> Ident {
Ident::new("b", Span::call_site())
}
#[test]
fn replace_lt_static() {
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<'static, T>), custom_lt("'a")),
parse_quote!(Foo<'static, T>),
);
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<'a, T>), custom_lt("'static")),
parse_quote!(Foo<'static, T>),
);
}
#[test]
fn replace_lt_ab() {
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<'a, 'b, T>), custom_lt("'c")),
parse_quote!(Foo<'c, 'b, T>),
);
assert_eq!(
replace_lifetime(
&b_ident(),
&parse_quote!(for<'a> fn(fn(Foo<'a, 'b, T>))),
custom_lt("'c"),
),
parse_quote!(for<'a> fn(fn(Foo<'a, 'c, T>))),
);
}
#[test]
fn replace_lt_macro() {
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(foo!(Foo<'a, T>)), custom_lt("'b")),
parse_quote!(foo!(Foo<'a, T>)),
);
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<'a, foo!(T)>), custom_lt("'b")),
parse_quote!(Foo<'b, foo!(T)>),
);
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<foo!('a), T>), custom_lt("'b")),
parse_quote!(Foo<foo!('a), T>),
);
}
#[test]
fn replace_raw() {
assert_eq!(
replace_lifetime(&a_ident(), &parse_quote!(Foo<'r#a, T>), custom_lt("'b")),
parse_quote!(Foo<'b, T>),
);
}
}