use syn::{parse_quote, Ident};
use crate::crate_path;
pub(crate) fn collect_generics_from_type(
ty: &syn::Type,
generics: &syn::Generics,
result: &mut Vec<Ident>,
) {
let mut visit = |ty: &syn::Type| {
if let syn::Type::Path(path) = ty {
if let Some(segment) = path.path.segments.last() {
if segment.ident == "PhantomData" {
return;
}
if let syn::PathArguments::AngleBracketed(args) = &segment.arguments {
for arg in &args.args {
if let syn::GenericArgument::Type(inner_ty) = arg {
collect_generics_from_type(inner_ty, generics, result);
}
}
}
for param in generics.type_params() {
if segment.ident == param.ident && !result.iter().any(|g| g == ¶m.ident) {
result.push(param.ident.clone());
}
}
}
}
};
visit(ty);
}
pub(crate) fn add_container_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
let container_path = crate_path("SensitiveType");
param.bounds.push(parse_quote!(#container_path));
}
}
generics
}
pub(crate) fn add_classified_value_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
let classifiable_path = crate_path("Classifiable");
param.bounds.push(parse_quote!(#classifiable_path));
}
}
generics
}
pub(crate) fn add_debug_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
param.bounds.push(parse_quote!(::core::fmt::Debug));
}
}
generics
}
pub(crate) fn add_display_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
param.bounds.push(parse_quote!(::core::fmt::Display));
}
}
generics
}
pub(crate) fn add_clone_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
param.bounds.push(parse_quote!(::core::clone::Clone));
}
}
generics
}
pub(crate) fn add_redacted_display_bounds(
mut generics: syn::Generics,
used_generics: &[Ident],
) -> syn::Generics {
for param in generics.type_params_mut() {
if used_generics.iter().any(|g| g == ¶m.ident) {
let redacted_display_path = crate_path("slog::RedactedDisplay");
param.bounds.push(parse_quote!(#redacted_display_path));
}
}
generics
}