From 7865c730064a5d1514e1b9be5da060bc539607b1 Mon Sep 17 00:00:00 2001 From: Noah Swerhun Date: Mon, 11 Mar 2024 20:22:08 -0500 Subject: [PATCH] praser done, using serde (amazing) --- Cargo.lock | 1 + Cargo.toml | 1 + src/config_file_parsing.rs | 106 ------- src/config_table.rs | 45 --- src/main.rs | 280 ++++-------------- src/ngen_toml.rs | 38 +++ src/parsed_config_processing/config_table.rs | 39 +++ src/parsed_config_processing/mod.rs | 4 + .../parsed_config_processing.rs | 12 + src/parsed_config_processing/target.rs | 151 ++++++++++ .../target_options.rs | 38 +++ src/target.rs | 90 ------ src/target_options.rs | 30 -- 13 files changed, 335 insertions(+), 500 deletions(-) delete mode 100644 src/config_file_parsing.rs delete mode 100644 src/config_table.rs create mode 100644 src/ngen_toml.rs create mode 100644 src/parsed_config_processing/config_table.rs create mode 100644 src/parsed_config_processing/mod.rs create mode 100644 src/parsed_config_processing/parsed_config_processing.rs create mode 100644 src/parsed_config_processing/target.rs create mode 100644 src/parsed_config_processing/target_options.rs delete mode 100644 src/target.rs delete mode 100644 src/target_options.rs diff --git a/Cargo.lock b/Cargo.lock index 09076b8..e39a45a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,7 @@ name = "ngen" version = "0.1.0" dependencies = [ "clap", + "serde", "toml", ] diff --git a/Cargo.toml b/Cargo.toml index 482c5ea..b10886e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] clap = { version = "4.5.1", features = ["derive", "std", "help", "usage"], default-features = false } +serde = { version = "1.0.197", features = ["derive"] } toml = "0.8.10" diff --git a/src/config_file_parsing.rs b/src/config_file_parsing.rs deleted file mode 100644 index ca4cb24..0000000 --- a/src/config_file_parsing.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::fmt::Display; - -use toml::{Table, Value}; - -#[derive(Debug)] -pub struct ConfigFileError<'a> { - pub key_path: String, - pub message: &'a str, -} - -impl Display for ConfigFileError<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "config file error: key {}: {}.", - self.key_path, self.message - ) - } -} - -pub fn get_key_as_str<'a>( - table: &'a Table, - key: &str, - key_path: String, -) -> Result, ConfigFileError<'a>> { - if let Some(v) = table.get(key) { - if let Value::String(s) = v { - Ok(Some(s)) - } else { - Err(ConfigFileError { - key_path, - message: "invalid type, should be string", - }) - } - } else { - Ok(None) - } -} - -pub fn get_key_as_table<'a>( - table: &'a Table, - key: &str, - key_path: String, -) -> Result, ConfigFileError<'a>> { - if let Some(v) = table.get(key) { - if let Value::Table(s) = v { - Ok(Some(s)) - } else { - Err(ConfigFileError { - key_path, - message: "invalid type, should be a table of key-value pairs", - }) - } - } else { - Ok(None) - } -} - -pub fn get_key_as_bool<'a>( - table: &'a Table, - key: &str, - key_path: String, -) -> Result, ConfigFileError<'a>> { - if let Some(v) = table.get(key) { - if let Value::Boolean(s) = v { - Ok(Some(*s)) - } else { - Err(ConfigFileError { - key_path, - message: "invalid type, should be boolean", - }) - } - } else { - Ok(None) - } -} - -pub fn get_key_as_vec_str<'a>( - table: &'a Table, - key: &str, - key_path: String, -) -> Result>, ConfigFileError<'a>> { - if let Some(v) = table.get(key) { - if let Value::Array(a) = v { - let mut ret: Vec<&'a str> = vec![]; - for elem in a { - if let Value::String(s) = elem { - ret.push(&s); - } else { - return Err(ConfigFileError { - key_path: format!("{key_path} elemement '{elem}'"), - message: "invalid type, should be string", - }); - } - } - Ok(Some(ret)) - } else { - Err(ConfigFileError { - key_path, - message: "invalid type, should be array of strings", - }) - } - } else { - Ok(None) - } -} diff --git a/src/config_table.rs b/src/config_table.rs deleted file mode 100644 index 84e0dee..0000000 --- a/src/config_table.rs +++ /dev/null @@ -1,45 +0,0 @@ -use toml::Table; - -use crate::config_file_parsing::*; - -#[derive(Debug, Clone)] -pub struct ConfigTable<'a> { - pub build_dir: &'a str, - pub compile_commands: bool, - pub compile_commands_target: &'a str, -} - -impl<'a> ConfigTable<'a> { - pub fn get_default() -> Self { - ConfigTable { - build_dir: "build", - compile_commands: false, - compile_commands_target: "main", - } - } - - pub fn from_table(table: &'a Table, key_path: String) -> Result> { - let mut ret = Self::get_default(); - - if let Some(v) = get_key_as_str(table, "build_dir", format!("{key_path}.build_dir"))? { - ret.build_dir = v; - } - - if let Some(v) = get_key_as_bool( - table, - "compile_commands", - format!("{key_path}.compile_commands"), - )? { - ret.compile_commands = v; - } - - if let Some(v) = get_key_as_str( - table, - "compile_commands_target", - format!("{key_path}.compile_commands_target"), - )? { - ret.compile_commands_target = v; - } - Ok(ret) - } -} diff --git a/src/main.rs b/src/main.rs index 6c72548..8505867 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,15 @@ use clap::Parser; -use config_file_parsing::get_key_as_table; -use core::{panic, str}; -use std::{ - fs::{read_to_string, write}, - path::Path, - process::exit, -}; -use toml::{Table, Value}; +use core::panic; +use std::collections::HashMap; +use std::fs::read_to_string; -mod target; -use target::*; +mod ngen_toml; +use ngen_toml::*; -mod config_table; -use config_table::*; - -mod config_file_parsing; -mod target_options; +mod parsed_config_processing; +use parsed_config_processing::config_table::*; +use parsed_config_processing::parsed_config_processing::*; +use parsed_config_processing::target::*; /// ngen is a build file generator for the ninja build system. #[derive(Parser)] @@ -32,226 +26,54 @@ struct Args { write_compile_commands: Option, } -fn gen_ninja_code(target: &Target) -> String { - let mut ret = String::from("\n"); - - // necessary because you cannot access struct members in a format string :( - let name = &target.name; - let outfile = &target.outfile; - let compiler = &target.compiler; - let compiler_flags = &target.compiler_flags.join(" "); - let linker = &target.linker; - let linker_flags = &target.linker_flags.join(" "); - let linker_libs = &target.linker_libs.join(" "); - let sources = &target.sources; - - ret.push_str(&format!( - "\ -# BEGIN TARGET {name} -rule cc_{name} - deps = gcc - depfile = $dep - command = {compiler} {compiler_flags} -MD -MF $dep -o $out -c $in - description = Building $in -> $out -rule link_{name} - command = {linker} {linker_flags} -o $out $in {linker_libs} - description = Linking $out - -build $builddir/{name}/obj: mkdir -build $builddir/{name}/dep: mkdir - -" - )); - - let mut object_list: Vec = Vec::new(); - - for s in sources { - let new_file = s.replace("/", "-"); - let obj_name = format!("$builddir/{name}/obj/{new_file}.o"); - let dep_name = format!("$builddir/{name}/dep/{new_file}.o.d"); - ret.push_str(&format!( - "build {obj_name}: cc_{name} {s}\n dep = {dep_name}\n" - )); - object_list.push(obj_name); - } - - ret.push_str(&format!("\nbuild $builddir/{name}/{outfile}: link_{name} ")); - ret.push_str(&object_list.join(" ")); - ret.push_str(&format!( - " || $builddir/{name}/obj $builddir/{name}/dep\nbuild {name}: phony $builddir/{name}/{outfile}\n" - )); - if target.is_default { - ret.push_str(&format!("\ndefault {name}\n")); - } - ret.push_str(&format!("# END TARGET {name}\n")); - - ret -} - -fn gen_compile_commands(target: &Target, build_dir: &str) -> String { - let mut ret = String::from("[\n"); - - let name = &target.name; - let compiler = &target.compiler; - let compiler_flags = &target.compiler_flags.join(" "); - - let pwd = Path::new("."); - let pwd = pwd - .canonicalize() - .unwrap_or_else(|e| panic!("cwd is non canonical (something is very wrong): {e}")); - let pwd = pwd.to_str().unwrap(); - - for (i, s) in target.sources.iter().enumerate() { - let new_file = s.replace("/", "-"); - let obj_name = format!("{build_dir}/{name}/obj/{new_file}.o"); - - ret.push_str(&format!( - " {{ - \"directory\": \"{pwd}\", - \"command\": \"{compiler} {compiler_flags} -o {obj_name} -c {s}\", - \"file\": \"{s}\" - }}" - )); - if i != target.sources.len() - 1 { - ret.push(','); - } - ret.push('\n'); - } - - ret.push_str("]\n"); - - ret -} - fn main() { let args = Args::parse(); - let output_file = &args.output_file; - let config_file_name = &args.config_file; - let config_file = read_to_string(config_file_name) - .unwrap_or_else(|e| panic!("could not read config file {config_file_name}: {e}")); - let toml_config = toml::from_str::(&config_file) - .unwrap_or_else(|e| panic!("error parsing toml file {config_file_name}: {e}")); + let config_file = read_to_string(&args.config_file) + .unwrap_or_else(|e| panic!("error reading config file `{}`: {e}", args.config_file)); + let toml_config: NgenToml = toml::from_str(&config_file) + .unwrap_or_else(|e| panic!("error parsing config file `{}`: {e}", args.config_file)); - // get config - let config_tbl: ConfigTable; - match get_key_as_table(&toml_config, "config", "".to_string()) { - Ok(v) => match v { - Some(c) => { - config_tbl = ConfigTable::from_table(&c, ".config".to_string()) - .unwrap_or_else(|e| panic!("{e}")) + let config_table: ConfigTable; + match &toml_config.config { + Some(v) => { + config_table = ConfigTable::from_parsed_config(&v).unwrap_or_else(|e| panic!("{e}")) + } + None => config_table = ConfigTable::get_default(), + } + + let all_parsed_targets: &HashMap; + match &toml_config.targets { + Some(v) => { + all_parsed_targets = v; + } + None => panic!( + "{}", + ConfigurationError { + message: "no targets found, nothing to do. Exiting".to_string() } - None => config_tbl = ConfigTable::get_default(), - }, - Err(e) => panic!("{e}"), - } - println!("{:?}", config_tbl); - //let mut config = Config::get_default(); - //if let Some(v) = parsed_config.get("config") { - // if let Value::Table(t) = v { - // config.set(&t); - // } else { - // panic!("error parsing config table: config invalid type, must be a table."); - // } - //} - //---- - - // parse the main target first - //let mut targets: Vec = vec![]; - - match Target::from_table(&toml_config, "main", "".to_string()) { - Ok(v) => println!("{:?}", v), - Err(e) => panic!("{e}"), + ), } - exit(10); + let mut targets: HashMap<&str, Target> = HashMap::new(); + for (name, parsed_target) in all_parsed_targets { + if let Some(_) = targets.get(name as &str) { + continue; + } + let mut inheritance_chain: HashMap<&str, &str> = HashMap::new(); + match Target::from_parsed_target( + parsed_target, + name, + all_parsed_targets, + &targets, + &mut inheritance_chain, + ) { + Ok(v) => { + targets.extend(v.into_iter()); + } + Err(e) => panic!("{e}"), + } + } - // targets.push(main_target.clone()); - // let mut target_for_comp_cmds = main_target; - // let mut target_for_comp_cmds_changed = false; - // - // // parse other targets - // for k in parsed_config.keys() { - // if let Value::Table(t) = parsed_config.get(k).unwrap() { - // if k == "config" { - // continue; // ignore config - // } - // let target = Target::new(&t, k, Some(&targets[0])); - // targets.push(target); - // if let Some(_) = args.write_compile_commands { - // if *k == config.compile_commands_target { - // target_for_comp_cmds = targets[targets.len() - 1].clone(); - // target_for_comp_cmds_changed = true; - // } - // } - // } - // } - // - // if let Some(file) = args.write_compile_commands { - // if config.compile_commands_target == "" { - // eprintln!( - // "ngen: warn: no compile_commands target found, using 'main' target by default." - // ); - // } else if !target_for_comp_cmds_changed && config.compile_commands_target != "main" { - // let c = &config.compile_commands_target; - // eprintln!( - // "ngen: warn: compile_commands target {c} not found, using 'main' target instead." - // ); - // } - // write( - // &file, - // &gen_compile_commands(&target_for_comp_cmds, &config.build_dir), - // ) - // .unwrap_or_else(|e| panic!("fatal: could not write {file}: {e}")); - // // no need to write ninja file - // exit(0); - // } - // - // let build_dir = &config.build_dir; - // let mut ninjafile = format!( - // "\ - //# Generated by ngen. Do not modify by hand. - // - //builddir = {build_dir} - // - //rule mkdir - // command = mkdir -p $out - // description = Creating directory $out - // - //rule regen_ninjafile - // command = ngen -c $in -o $out - // generator = 1 - // description = Regenerating $out - // - //", - // ); - // - // if config.compile_commands { - // ninjafile.push_str(&format!( - // "\ - //rule regen_compile_commands - // command = ngen -c $in --write-compile-commands $out - // description = Regenerating $out - // - //build $builddir: mkdir - // - //build $builddir/compile_commands.json: regen_compile_commands {config_file_name} || $builddir - // pool = console - // - //build {output_file}: regen_ninjafile {config_file_name} || $builddir/compile_commands.json - // pool = console - //" - // )); - // } else { - // ninjafile.push_str(&format!( - // "build {output_file}: regen_ninjafile {config_file_name}\n pool = console\n" - // )); - // } - // - // for t in targets { - // ninjafile.push_str(&gen_ninja_code(&t)); - // } - // - // write(output_file, &ninjafile) - // .unwrap_or_else(|e| panic!("could not write ninja file {ninjafile}: {e}")); + println!("{:#?}", targets); } diff --git a/src/ngen_toml.rs b/src/ngen_toml.rs new file mode 100644 index 0000000..f608c73 --- /dev/null +++ b/src/ngen_toml.rs @@ -0,0 +1,38 @@ +use serde::Deserialize; +use std::collections::HashMap; + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ParsedTarget { + pub outfile: Option, + pub compiler: Option, + pub compiler_flags: Option>, + pub linker: Option, + pub linker_flags: Option>, + pub linker_libs: Option>, + pub sources: Option>, + pub opts: Option, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ParsedTargetOptions { + pub inherit: Option, + pub inherit_from: Option, + pub default: Option, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ParsedConfigTable { + pub build_dir: Option, + pub compile_commands: Option, + pub compile_commands_target: Option, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct NgenToml { + pub config: Option, + pub targets: Option>, +} diff --git a/src/parsed_config_processing/config_table.rs b/src/parsed_config_processing/config_table.rs new file mode 100644 index 0000000..270b7c2 --- /dev/null +++ b/src/parsed_config_processing/config_table.rs @@ -0,0 +1,39 @@ +use super::parsed_config_processing::*; +use crate::ngen_toml::*; + +#[derive(Debug, Clone)] +pub struct ConfigTable<'a> { + pub build_dir: &'a str, + pub compile_commands: bool, + pub compile_commands_target: &'a str, +} + +impl<'a> ConfigTable<'a> { + pub fn get_default() -> Self { + ConfigTable { + build_dir: "build", + compile_commands: false, + compile_commands_target: "main", + } + } + + pub fn from_parsed_config( + parsed_config_table: &'a ParsedConfigTable, + ) -> Result { + let mut ret = Self::get_default(); + + if let Some(v) = &parsed_config_table.build_dir { + ret.build_dir = v; + } + + if let Some(v) = &parsed_config_table.compile_commands { + ret.compile_commands = *v; + } + + if let Some(v) = &parsed_config_table.compile_commands_target { + ret.compile_commands_target = v; + } + + Ok(ret) + } +} diff --git a/src/parsed_config_processing/mod.rs b/src/parsed_config_processing/mod.rs new file mode 100644 index 0000000..d1ee3fd --- /dev/null +++ b/src/parsed_config_processing/mod.rs @@ -0,0 +1,4 @@ +pub mod config_table; +pub mod parsed_config_processing; +pub mod target; +pub mod target_options; diff --git a/src/parsed_config_processing/parsed_config_processing.rs b/src/parsed_config_processing/parsed_config_processing.rs new file mode 100644 index 0000000..7d18680 --- /dev/null +++ b/src/parsed_config_processing/parsed_config_processing.rs @@ -0,0 +1,12 @@ +use std::fmt::Display; + +#[derive(Debug)] +pub struct ConfigurationError { + pub message: String, +} + +impl Display for ConfigurationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "configuration error: {}", self.message) + } +} diff --git a/src/parsed_config_processing/target.rs b/src/parsed_config_processing/target.rs new file mode 100644 index 0000000..3763f41 --- /dev/null +++ b/src/parsed_config_processing/target.rs @@ -0,0 +1,151 @@ +use core::str; +use std::collections::HashMap; + +use super::parsed_config_processing::*; +use super::target_options::*; +use crate::ngen_toml::*; + +#[derive(Debug, Clone)] +pub struct Target<'a> { + pub outfile: &'a str, + pub compiler: &'a str, + pub compiler_flags: Vec<&'a str>, + pub linker: &'a str, + pub linker_flags: Vec<&'a str>, + pub linker_libs: Vec<&'a str>, + pub sources: Vec<&'a str>, + pub opts: TargetOptions<'a>, +} + +impl<'a> Target<'a> { + pub fn get_default( + ) -> Self { + Target { + outfile: "a.out", + compiler: "cc", + compiler_flags: vec![], + linker: "cc", + linker_flags: vec![], + linker_libs: vec![], + sources: vec![], + opts: TargetOptions::get_default(), + } + } + pub fn from_parsed_target( + parsed_target: &'a ParsedTarget, + name: &'a str, + all_parsed_targets: &'a HashMap, + all_targets: &HashMap<&'a str, Target<'a>>, + inheritance_chain: &mut HashMap<&'a str, &'a str> + ) -> Result>, ConfigurationError> { + let mut retmap: HashMap<&str, Target> = HashMap::new(); + let mut ret = Self::get_default(); + + if ret.opts.inherit_from == name { + ret.opts.inherit = false; + } + + if let Some(v) = &parsed_target.opts { + ret.opts = TargetOptions::from_parsed_target_options(v)?; + } + + if ret.opts.inherit { + let inherit_target: Target; + + match all_targets.get(ret.opts.inherit_from) { + Some(v) => { + inherit_target = v.clone() + } + None => { + match all_parsed_targets.get(ret.opts.inherit_from) { + Some(v) => { + let inherited_targets: HashMap<&str, Target>; + if let Some(_) = inheritance_chain.get(ret.opts.inherit_from) { + let mut message = format!("inheritance dependency cylce detected: "); + for (targ_name, depends_on) in inheritance_chain { + message.push_str(&format!("`{}` depends on `{}`, ", targ_name, depends_on)); + } + message.push_str(&format!("and `{}` depends on `{}`", name, ret.opts.inherit_from)); + return Err(ConfigurationError { message }); + } + inheritance_chain.insert(name, ret.opts.inherit_from); + inherited_targets = Self::from_parsed_target(v, ret.opts.inherit_from, all_parsed_targets, all_targets, inheritance_chain)?; + inherit_target = inherited_targets.get(ret.opts.inherit_from).unwrap().clone(); + retmap.extend(inherited_targets.into_iter()); + } + None => { + return Err(ConfigurationError { + message: + format!("target `{0}` trying to inherit from target `{1}`, but target `{1}` does not exist", + name, + ret.opts.inherit_from) + }); + } + } + } + } + + + if let None = parsed_target.outfile { + ret.outfile = inherit_target.outfile; + } + if let None = parsed_target.compiler { + ret.compiler = inherit_target.compiler; + } + if let None = parsed_target.linker { + ret.linker = inherit_target.linker; + } + + for string in inherit_target.compiler_flags { + ret.compiler_flags.push(string); + } + for string in inherit_target.linker_flags { + ret.linker_flags.push(string); + } + for string in inherit_target.linker_libs { + ret.linker_libs.push(string); + } + for string in inherit_target.sources { + ret.sources.push(string); + } + } + + if let Some(v) = &parsed_target.outfile { + ret.outfile = v; + } + if let Some(v) = &parsed_target.compiler { + ret.compiler = v; + } + if let Some(v) = &parsed_target.compiler_flags { + for string in v { + ret.compiler_flags.push(string); + } + } + if let Some(v) = &parsed_target.linker { + ret.linker = v; + } else { + if let Some(v) = &parsed_target.compiler { + ret.linker = v; + } + } + if let Some(v) = &parsed_target.linker_flags { + for string in v { + ret.linker_flags.push(string); + } + } + if let Some(v) = &parsed_target.linker_libs { + for string in v { + ret.linker_libs.push(string); + } + } + if let Some(v) = &parsed_target.sources { + for string in v { + ret.sources.push(string); + } + } + + retmap.insert(name, ret); + + Ok(retmap) + } +} diff --git a/src/parsed_config_processing/target_options.rs b/src/parsed_config_processing/target_options.rs new file mode 100644 index 0000000..c6b7a44 --- /dev/null +++ b/src/parsed_config_processing/target_options.rs @@ -0,0 +1,38 @@ +use super::parsed_config_processing::*; +use crate::ngen_toml::*; + +#[derive(Debug, Clone)] +pub struct TargetOptions<'a> { + pub inherit: bool, + pub inherit_from: &'a str, + pub default: bool, +} + +impl<'a> TargetOptions<'a> { + pub fn get_default() -> Self { + TargetOptions { + inherit: true, + inherit_from: "main", + default: false, + } + } + pub fn from_parsed_target_options( + parsed_target_options: &'a ParsedTargetOptions, + ) -> Result { + let mut ret = Self::get_default(); + + if let Some(v) = &parsed_target_options.inherit { + ret.inherit = *v; + } + + if let Some(v) = &parsed_target_options.inherit_from { + ret.inherit_from = v; + } + + if let Some(v) = &parsed_target_options.default { + ret.default = *v; + } + + Ok(ret) + } +} diff --git a/src/target.rs b/src/target.rs deleted file mode 100644 index e2cd0ef..0000000 --- a/src/target.rs +++ /dev/null @@ -1,90 +0,0 @@ -use toml::Table; - -use crate::config_file_parsing::*; -use crate::target_options::*; - -#[derive(Debug, Clone)] -pub struct Target<'a> { - pub name: &'a str, - pub outfile: &'a str, - pub compiler: &'a str, - pub compiler_flags: Vec<&'a str>, - pub linker: &'a str, - pub linker_flags: Vec<&'a str>, - pub linker_libs: Vec<&'a str>, - pub sources: Vec<&'a str>, - pub is_default: bool, - pub opts: TargetOptions<'a>, -} - -impl<'a> Target<'a> { - pub fn get_default() -> Self { - Target { - name: "", - outfile: "a.out", - compiler: "cc", - compiler_flags: vec![""], - linker: "cc", - linker_flags: vec![""], - linker_libs: vec![""], - sources: vec![""], - is_default: false, - opts: TargetOptions::get_default(), - } - } - pub fn from_table( - table: &'a Table, - name: &'a str, - key_path: String, - ) -> Result> { - let mut ret = Self::get_default(); - - if let Some(v) = get_key_as_table(table, "opts", format!("{key_path}.opts"))? { - ret.opts = TargetOptions::from_table(&v, format!("{key_path}.opts"))?; - } - - ret.name = name; - - if let Some(v) = get_key_as_str(table, "outfile", format!("{key_path}.outfile"))? { - ret.outfile = v; - } - - if let Some(v) = get_key_as_str(table, "compiler", format!("{key_path}.compiler"))? { - ret.compiler = v; - } - - if let Some(v) = get_key_as_vec_str( - table, - "compiler_flags", - format!("{key_path}.compiler_flags"), - )? { - ret.compiler_flags = v; - } - - if let Some(v) = get_key_as_str(table, "linker", format!("{key_path}.linker"))? { - ret.linker = v; - } - - if let Some(v) = - get_key_as_vec_str(table, "linker_flags", format!("{key_path}.linker_flags"))? - { - ret.linker_flags = v; - } - - if let Some(v) = - get_key_as_vec_str(table, "linker_libs", format!("{key_path}.linker_libs"))? - { - ret.linker_libs = v; - } - - if let Some(v) = get_key_as_vec_str(table, "sources", format!("{key_path}.sources"))? { - ret.sources = v; - } - - if let Some(v) = get_key_as_bool(table, "is_default", format!("{key_path}.is_default"))? { - ret.is_default = v; - } - - Ok(ret) - } -} diff --git a/src/target_options.rs b/src/target_options.rs deleted file mode 100644 index 6a2c027..0000000 --- a/src/target_options.rs +++ /dev/null @@ -1,30 +0,0 @@ -use toml::{Table, Value}; - -use crate::config_file_parsing::*; - -#[derive(Debug, Clone)] -pub struct TargetOptions<'a> { - pub inherit: bool, - pub inherit_from: &'a str, -} - -impl<'a> TargetOptions<'a> { - pub fn get_default() -> Self { - TargetOptions { - inherit: true, - inherit_from: "main", - } - } - pub fn from_table(table: &'a Table, key_path: String) -> Result> { - let mut ret = Self::get_default(); - - if let Some(v) = get_key_as_bool(table, "inherit", format!("{key_path}.inherit"))? { - ret.inherit = v; - } - if let Some(v) = get_key_as_str(table, "inherit_from", format!("{key_path}.inherit_from"))? - { - ret.inherit_from = v; - } - Ok(ret) - } -}