use std::{ fmt::format, fs::{read_to_string, File}, io::{BufWriter, Write}, process::exit, }; use error_stack::Report; use crate::Error; pub struct Package { name: String, binaries: Vec, build_cmd: String, } impl Package { pub fn load_from_file(path: String) -> Self { let contents = match std::fs::read_to_string(path.clone()) { // If successful return the files text as `contents`. // `c` is a local variable. Ok(c) => c, // Handle the `error` case. Err(_) => { // Write `msg` to `stderr`. eprintln!("Could not read file `{}`", path); // Exit the program with exit code `1`. exit(1); } }; use toml::Value; let mut data: Value = toml::from_str(&contents).unwrap(); let mut name = data .get("package") .unwrap() .get("name") .unwrap() .to_string(); name.pop(); name.remove(0); let dependants = data.get("dependants").unwrap(); let bin_table = dependants.get("binaries").unwrap().as_table().unwrap(); let mut binaries = vec![]; for (count, (name, table)) in bin_table.into_iter().enumerate() { // if count != 0 { println!("{}", name); binaries.push(name.clone()); // } } let build_table = data.get("build").unwrap(); let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into(); build_cmd.remove(0); // build_cmd.pop(); Self { name, binaries, build_cmd, } } pub fn build(&self) { if self.binaries.contains(&"hblang".to_string()) { let file_order = self.build_cmd.split_ascii_whitespace(); let mut files = vec![]; for (count, file) in file_order.enumerate() { if count != 0 { files.push(file); } } let mut bundle = vec![]; for file in files { let file_path = if file.starts_with("libraries") { format!("sysdata/{}", file) } else { format!("sysdata/programs/{}/{}", self.name, file) }; let contents = read_to_string(file_path).unwrap(); bundle.push((file, contents)); } use hblang::{codegen, parser}; let mut codegen = codegen::Codegen::default(); for (path, content) in bundle.iter() { codegen.files = vec![parser::Ast::new(path, content, &parser::no_loader)]; codegen.generate(); } let mut buf = BufWriter::new(Vec::new()); codegen.dump(&mut buf); let bytes = buf.into_inner().unwrap(); match std::fs::create_dir("target/programs") { Ok(_) => (), Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (), Err(e) => panic!(), } let path = format!("target/programs/{}.hbf", self.name); let mut file = File::create(path).unwrap(); file.write_all(&bytes).unwrap(); } } }