use proc_macro2::TokenStream;
use quote::{
quote,
quote_spanned,
};
use syn::{
Path,
spanned::Spanned,
};
use crate::{
field_assertion,
field_mode::FieldMode,
};
#[must_use]
#[inline(always)]
pub(super) fn field_is_skipped(
mode: &FieldMode,
serde_attributes: &crate::serde_attributes::SerdeAttributes,
) -> bool {
matches!(mode, FieldMode::Skip) || serde_attributes.skip()
}
#[inline]
pub(super) fn serialization_condition(
serde_attributes: &crate::serde_attributes::SerdeAttributes,
raw: TokenStream,
) -> TokenStream {
serde_attributes
.skip_serializing_if()
.map_or_else(|| quote!(true), |predicate| quote!(!(#predicate)(#raw)))
}
pub(super) fn serialized_carrier(
type_name: &syn::Ident,
field: &syn::Field,
context: &str,
mode: &FieldMode,
runtime: &Path,
serialize_with: Option<&Path>,
raw: TokenStream,
) -> TokenStream {
match mode {
FieldMode::Plain => match serialize_with {
Some(_path) => {
let helper = field_assertion::helper_name(
type_name,
field,
context,
"SerializeWith",
);
quote_spanned!(field.span()=> #helper(#raw))
}
None => raw,
},
FieldMode::Level(sensitivity) => {
let level = sensitivity.runtime_tokens(runtime);
quote_spanned! {field.span()=>
#runtime::RedactValue::redact_value(
#raw,
#level,
policy.masking(),
)
}
}
FieldMode::Nested => {
let helper = field_assertion::helper_name(
type_name,
field,
context,
"RedactSerialize",
);
quote_spanned!(field.span()=> #helper(#raw, policy))
}
FieldMode::Map => {
let helper = field_assertion::helper_name(
type_name,
field,
context,
"RedactMapSerialize",
);
quote_spanned!(field.span()=> #helper(#raw, policy))
}
FieldMode::Json => quote_spanned! {field.span()=>
#runtime::__qubit_redact_json! {
#runtime::RedactedJsonText::new(#raw, policy)
}
},
FieldMode::Skip => TokenStream::new(),
}
}
#[inline]
pub(super) fn raw_identifier(identifier: &syn::Ident) -> String {
identifier
.to_string()
.strip_prefix("r#")
.map_or_else(|| identifier.to_string(), str::to_owned)
}
#[inline]
pub(super) fn field_context(
variant_name: Option<&syn::Ident>,
variant_index: Option<u32>,
field_name: &str,
) -> String {
variant_name.map_or_else(
|| field_name.to_owned(),
|variant| {
let index = variant_index.expect(
"enum variant field contexts require a declaration index",
);
format!("{variant}_{index}_{field_name}")
},
)
}