use crate::{
macros::{config::trixy::TrixyConfig, generate::host::format_rust},
parser::command_spec::{CommandSpec, Namespace},
};
use proc_macro2::TokenStream as TokenStream2;
pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
let host_rust_code = generate_code(&trixy, &config);
let rust_code = format_rust(host_rust_code);
format!(
"\
/* C API */\n\
// Workaround rust rules when implementing a foreign trait on a foreign type
#[derive(Debug)]
pub struct OurResult<T, E> {{
value: Result<T, E>,
}}
impl<T, E> std::ops::Deref for OurResult<T, E> {{
type Target = Result<T, E>;
fn deref(&self) -> &Self::Target {{
&self.value
}}
}}
impl<T, E> From<Result<T, E>> for OurResult<T, E> {{
fn from(value: Result<T, E>) -> Self {{
Self {{ value }}
}}
}}
#[derive(Debug)]
pub struct OurOption<T> {{
value: Option<T>,
}}
impl<T> std::ops::Deref for OurOption<T> {{
type Target = Option<T>;
fn deref(&self) -> &Self::Target {{
&self.value
}}
}}
impl<T> From<Option<T>> for OurOption<T> {{
fn from(value: Option<T>) -> Self {{
Self {{ value }}
}}
}}
#[derive(Debug)]
pub struct OurVec<T> {{
value: Vec<T>,
}}
impl<T> std::ops::Deref for OurVec<T> {{
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {{
&self.value
}}
}}
impl<T> From<Vec<T>> for OurVec<T> {{
fn from(value: Vec<T>) -> Self {{
Self {{ value }}
}}
}}
/* The real C API */\n\
{}",
rust_code
)
}
pub fn generate_code(trixy: &CommandSpec, config: &TrixyConfig) -> TokenStream2 {
let root_namespace = Namespace::from(trixy);
root_namespace.to_c(config, &vec![])
}