use crate::codegen::error::CodegenError;
use itertools::Itertools;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn generate_serde_attrs(derives: &[&str]) -> TokenStream {
if derives.contains(&"Serialize") || derives.contains(&"Deserialize") {
quote!(
#[serde(crate = "self::serde")]
)
} else {
TokenStream::new()
}
}
pub fn generate_root(
names: &[&str],
derives: &[&str],
prelude_import_location: &str,
non_exhaustive: bool,
) -> Result<TokenStream, CodegenError> {
let serde_attrs = generate_serde_attrs(derives);
let names = names.iter().map(|i| format_ident!("{}", i)).collect_vec();
let prelude_import_location = format_ident!("{}", prelude_import_location);
let derives = derives.iter().map(|i| format_ident!("{}", i)).collect_vec();
let non_exhaustive = if non_exhaustive {
quote!(
#[derive(Copy, Clone, #(#derives),*)]
#serde_attrs
pub struct NonExhaustive;
)
} else {
TokenStream::new()
};
Ok(quote!(
#(
mod #names;
pub use #names::*;
)*
mod prelude {
pub use #prelude_import_location::codegen_prelude::*;
pub use super::*;
#non_exhaustive
}
))
}
pub fn generate_parser(parser: &[u8]) -> Result<TokenStream, CodegenError> {
Ok(quote!(
pub const PARSER: &[u8] = &[#(#parser),*];
))
}