use super::{VarType, TreeCursor, types};
type StructDecl = (String, Vec<(VarType, String)>);
pub fn parse(cursor: &mut TreeCursor, code: &str) -> StructDecl {
cursor.goto_first_child();
cursor.goto_next_sibling();
let struct_name = code[cursor.node().byte_range()].to_string();
cursor.goto_next_sibling();
let fields = get_fields(cursor, code);
cursor.goto_parent();
(struct_name, fields)
}
pub fn transpile(struct_decl: &StructDecl) -> String {
let struct_name = &struct_decl.0;
let mut fields_str = String::new();
struct_decl
.1
.iter()
.map(|field| format!("{}: {},\n", field.1, types::transpile(&field.0)))
.for_each(|field| fields_str.push_str(&field));
fields_str.pop();
format!("#[derive(Clone)]\nstruct {struct_name} {{\n{fields_str}\n}}")
}
fn get_fields(cursor: &mut TreeCursor, code: &str) -> Vec<(VarType, String)> {
let mut fields = vec![];
while cursor.goto_next_sibling() {
let node_kind = cursor.node().kind();
fields.push(match node_kind {
"{" | "," => continue,
"}" => break,
"struct_field" => {
cursor.goto_first_child();
let field_type = types::parse(cursor, code);
cursor.goto_next_sibling();
let field_name = code[cursor.node().byte_range()].to_string();
cursor.goto_parent();
(field_type, field_name)
}
_ => todo!(),
});
}
fields
}