use std::{collections::HashMap, io::Error};
use envl_utils::case::{CamelCase, Case, SnakeCase};
use envl_utils::variable::{Type, Value};
use proc_macro2::TokenStream;
use quote::quote;
use crate::generator::rust::var::gen_value;
pub fn gen_struct(
name: String,
t: HashMap<String, Type>,
v: HashMap<String, Value>,
structs: &mut Vec<TokenStream>,
) -> Result<TokenStream, Error> {
let struct_type = format!("Struct{}", name).parse::<TokenStream>().unwrap();
let struct_name = SnakeCase::gen(CamelCase::parse(format!("struct{}", name).as_str()))
.parse::<TokenStream>()
.unwrap();
let mut struct_values = Vec::new();
for (n, element_type) in t {
if let Some(value) = v.get(&n) {
let element_name = match value {
Value::Struct(_) => {
format!("{}{}", struct_type, n.to_owned())
}
_ => n.to_owned(),
};
match gen_value(
element_name.to_owned(),
element_type.to_owned(),
value.to_owned(),
structs,
) {
Ok(r) => {
struct_values.push((n.to_owned(), r));
}
Err(err) => {
return Err(err);
}
}
} else {
return Err(Error::other(""));
}
}
let elements = struct_values
.iter()
.map(|(n, v)| {
let name = n.parse::<TokenStream>().unwrap();
quote! {#name: #v}
})
.collect::<Vec<_>>();
structs.push(quote! {
let #struct_name = #struct_type {
#(
#elements,
)*
};
});
Ok(quote! {
#struct_name
})
}