use crate::core::models::rust::RustDbSetAttribute;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::File;
pub fn pretty_print_tokenstream(ts: proc_macro2::TokenStream) -> String {
match syn::parse2::<File>(ts.clone()) {
Ok(file) => prettyplease::unparse(&file).to_string(),
Err(err) => format!("Failed to parse TokenStream: {err}. Stream was {ts}"),
}
}
pub fn get_attributes(attributes: &[RustDbSetAttribute]) -> TokenStream {
if attributes.is_empty() {
return quote! {};
}
let struct_fields_tokens = attributes
.iter()
.map(|attribute| {
let attribute_name = format_ident!("{}", attribute.attribute_name);
if attribute.attribute_args.is_empty() {
return quote! {
#[#attribute_name]
};
}
let attribute_args = attribute.attribute_args.iter().map(|a| {
let arg_name = format_ident!("{}", a.name);
if let Some(arg_value) = &a.value {
quote! { #arg_name = #arg_value }
} else {
quote! { #arg_name }
}
});
quote! {
#[#attribute_name(#(#attribute_args),*)]
}
})
.collect::<Vec<_>>();
quote! {
#(#struct_fields_tokens)*
}
}
pub fn get_derives(derives: &[String]) -> TokenStream {
if derives.is_empty() {
return quote! {};
}
let struct_derives = derives
.iter()
.map(|derive| syn::parse_str::<syn::Path>(derive).unwrap())
.collect::<Vec<_>>();
quote! {
#[derive(#(#struct_derives),*)]
}
}
pub fn sanitize_field_name(name: &str) -> proc_macro2::Ident {
let reserved_keywords = [
"as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn",
"for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref",
"return", "self", "Self", "static", "struct", "super", "trait", "true", "type", "unsafe",
"use", "where", "while", "async", "await", "dyn",
];
if reserved_keywords.contains(&name) {
format_ident!("r#{}", name)
} else {
format_ident!("{}", name)
}
}