use proc_macro2::{Ident, Span, TokenStream};
use quote::quote_spanned;
use crate::{
crate_root,
generics::{push_container_predicate, push_debug_predicate, push_policy_predicate},
strategy::Strategy,
};
pub(crate) struct DeriveContext<'a> {
pub(crate) container_path: &'a TokenStream,
pub(crate) container_predicates: &'a mut Vec<syn::WherePredicate>,
pub(crate) policy_predicates: &'a mut Vec<syn::WherePredicate>,
pub(crate) debug_unredacted_predicates: &'a mut Vec<syn::WherePredicate>,
pub(crate) mapper: &'a Ident,
}
pub(crate) fn generate_field_transform(
ctx: &mut DeriveContext<'_>,
ty: &syn::Type,
binding: &Ident,
span: Span,
strategy: &Strategy,
recursive_bound_override: bool,
) -> TokenStream {
let container_path = ctx.container_path;
let mapper = ctx.mapper;
match strategy {
Strategy::WalkDefault => {
if !recursive_bound_override {
push_container_predicate(ctx.container_predicates, ty);
push_debug_predicate(ctx.debug_unredacted_predicates, ty);
}
quote_spanned! { span =>
let #binding = #container_path::redact_with(#binding, #mapper);
}
}
Strategy::NotSensitive => {
if !recursive_bound_override {
push_debug_predicate(ctx.debug_unredacted_predicates, ty);
}
TokenStream::new()
}
Strategy::Policy(policy_path) => {
if !recursive_bound_override {
push_policy_predicate(ctx.policy_predicates, ty, policy_path);
push_debug_predicate(ctx.debug_unredacted_predicates, ty);
}
let policy = policy_path.clone();
let crate_root = crate_root();
quote_spanned! { span =>
let #binding = <#ty as #crate_root::__private::PolicyField<#policy>>::apply_field(
#binding,
#mapper,
);
}
}
}
}