use quote::{ToTokens, quote};
use syn::{Attribute, Meta, Token, punctuated::Punctuated};
use super::quote_mixed;
pub(crate) fn generated_impl_attributes(attributes: &[Attribute]) -> proc_macro2::TokenStream {
let lints = generated_lint_attributes(attributes);
quote!(#[automatically_derived] #lints)
}
pub(crate) fn generated_lint_attributes(attributes: &[Attribute]) -> proc_macro2::TokenStream {
let mut token_stream = proc_macro2::TokenStream::new();
for attribute in attributes {
let path = attribute.path();
if path.is_ident("expect") {
if let Meta::List(list) = &attribute.meta {
let lints = &list.tokens;
token_stream.extend(quote!(#[allow(#lints)]));
}
} else if path.is_ident("allow") || path.is_ident("warn") || path.is_ident("deny") {
attribute.to_tokens(&mut token_stream);
}
}
token_stream
}
pub(crate) fn is_packed(attributes: &[Attribute]) -> bool {
for attribute in attributes {
if attribute.path().is_ident("repr")
&& let Meta::List(list) = &attribute.meta
&& let Ok(items) = list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
{
for item in items {
if item.path().is_ident("packed") {
return true;
}
}
}
}
false
}
pub(crate) fn borrow_field<T: ToTokens>(
is_packed: bool,
receiver: &proc_macro2::TokenStream,
field_name: &T,
) -> proc_macro2::TokenStream {
if is_packed {
quote_mixed!(&{ #receiver.#field_name })
} else {
quote_mixed!(&#receiver.#field_name)
}
}