use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use crate::parser::command_spec::{
Attribute, Enumeration, Function, Identifier, Namespace, Structure, Type, Variant,
};
impl Namespace {
pub fn to_auxiliary_c(&self, namespaces: &Vec<&Identifier>) -> String {
let mut nasps = namespaces.clone();
if self.name.variant != Variant::RootNamespace {
nasps.push(&self.name);
}
let structures: String = self
.structures
.iter()
.map(Structure::to_auxiliary_c)
.collect::<Vec<String>>()
.join("\n");
let enumerations: String = self
.enumerations
.iter()
.map(Enumeration::to_auxiliary_c)
.collect::<Vec<String>>()
.join("\n");
let results: String = self
.select_types_pred(|(ident, _generics)| ident.name.as_str() == "Result")
.iter()
.map(|(ident, generics)| Type::to_auxilary_c_result(ident, generics).to_string())
.collect::<Vec<String>>()
.join("\n");
let options: String = self
.select_types_pred(|(ident, _generics)| ident.name.as_str() == "Option")
.iter()
.map(|(ident, generics)| Type::to_auxilary_c_option(ident, generics).to_string())
.collect::<Vec<String>>()
.join("\n");
let vectors: String = self
.select_types_pred(|(ident, _generics)| ident.name.as_str() == "Vec")
.iter()
.map(|(ident, generics)| Type::to_auxilary_c_vector(ident, generics).to_string())
.collect::<Vec<String>>()
.join("\n");
let functions: String = self
.functions
.iter()
.map(|r#fn| r#fn.to_auxiliary_c(&nasps))
.collect::<Vec<String>>()
.join("\n");
let namespaces: String = self
.namespaces
.iter()
.map(|nasp| nasp.to_auxiliary_c(&nasps))
.collect();
format! {"\
{enumerations}\n\
{structures}\n\
{options}\n\
{results}\n\
{vectors}\n\
{functions}\n\
{namespaces}"}
}
pub fn to_auxiliary_c_full_struct_init(&self, namespaces: &Vec<&Identifier>) -> TokenStream2 {
let mut input_namespaces = namespaces.clone();
input_namespaces.push(&self.name);
let ident = &self.name.to_rust();
let type_ident = ident.clone();
let functions: TokenStream2 = self
.functions
.iter()
.map(|r#fn| r#fn.to_auxiliary_c_namespace_init(&input_namespaces))
.collect();
let namespaces: TokenStream2 = self
.namespaces
.iter()
.map(Namespace::to_auxiliary_c_namespace_init)
.collect();
let next_namespace: TokenStream2 = self
.namespaces
.iter()
.map(|nasp| nasp.to_auxiliary_c_full_struct_init(&input_namespaces))
.collect();
quote! {
#next_namespace
const struct #type_ident #ident = {
#functions
#namespaces
};
}
}
pub fn to_auxiliary_c_typedef(&self) -> TokenStream2 {
let ident = &self.name.to_rust();
let type_ident = ident.clone();
quote! {
struct #type_ident #ident;
}
}
pub fn to_auxiliary_c_full_typedef(&self) -> String {
let ident = format_ident!("{}", self.name.name);
let doc_comments: String = Attribute::to_auxiliary_c_merged(&self.attributes);
let functions: TokenStream2 = self
.functions
.iter()
.map(Function::to_auxiliary_c_typedef)
.collect();
let namespaces: TokenStream2 = self
.namespaces
.iter()
.map(Namespace::to_auxiliary_c_typedef)
.collect();
let next_namespace: String = self
.namespaces
.iter()
.map(Namespace::to_auxiliary_c_full_typedef)
.collect::<Vec<String>>()
.join("\n");
let namespace = quote! {
struct #ident {
#functions
#namespaces
};
};
format! {"{}\n{}{}\n", next_namespace, doc_comments, namespace}
}
pub fn to_auxiliary_c_namespace_init(&self) -> TokenStream2 {
let ident = self.name.to_rust();
quote! {
. #ident = #ident ,
}
}
}