diff --git a/README.md b/README.md index c41d657..34e0081 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,14 @@ Simply run `trmt` in your terminal to start a simulation. trmt ``` +You can also pass a rule and/or seed directly: +```bash +trmt --rule RL --seed abc123 +trmt -r 'R1>1,L0>2' -s myseed +``` +> [!NOTE] +> Quote rules containing special characters (`>`, `,`, `{`, `}`, etc.) to prevent shell interpretation. + #### Examples Check out the [examples](/examples) to see some of the possibilities. diff --git a/src/config/mod.rs b/src/config/mod.rs index 38f356c..0da9cae 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -144,6 +144,15 @@ impl Config { Ok(()) } + pub fn apply_cli_overrides(rule: Option<&str>, seed: Option<&str>) { + if let Some(rule) = rule { + let _ = Self::save_current_rule(rule); + } + if let Some(seed) = seed { + let _ = Self::save_current_seed(seed); + } + } + pub fn validate(&self) -> Result<(), Vec> { validation::validate_config(self) } diff --git a/src/main.rs b/src/main.rs index 9856636..4ae00af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,8 @@ use config::{Config, ConfigLoadResult}; use render::{App, ui}; fn main() -> Result<(), Box> { + let (cli_rule, cli_seed) = parse_cli_args(); + let (config, error_message) = match Config::load() { ConfigLoadResult::Success(config) => (config, None), ConfigLoadResult::ValidationErrors(config, errors) => { @@ -34,6 +36,8 @@ fn main() -> Result<(), Box> { }, }; + Config::apply_cli_overrides(cli_rule.as_deref(), cli_seed.as_deref()); + enable_raw_mode()?; let mut stdout = io::stdout(); execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; @@ -64,6 +68,55 @@ fn main() -> Result<(), Box> { Ok(()) } +fn parse_cli_args() -> (Option, Option) { + let mut rule = None; + let mut seed = None; + let mut args = std::env::args().skip(1); + + while let Some(arg) = args.next() { + match arg.as_str() { + "--help" | "-h" => { + println!("trmt {}", env!("CARGO_PKG_VERSION")); + println!(); + println!("usage: trmt [options]"); + println!(); + println!("options:"); + println!(" -r, --rule Override the simulation rule"); + println!(" -s, --seed Override the simulation seed"); + println!(" -h, --help Show this help message"); + println!(" -v, --version Show version"); + println!(); + println!("note: quote rules with special characters: --rule 'R1>1,L0>2'"); + std::process::exit(0); + } + "--version" | "-v" => { + println!("trmt {}", env!("CARGO_PKG_VERSION")); + std::process::exit(0); + } + "--rule" | "-r" => { + rule = Some(args.next().unwrap_or_else(|| { + eprintln!("error: --rule requires a value"); + std::process::exit(1); + })); + } + "--seed" | "-s" => { + seed = Some(args.next().unwrap_or_else(|| { + eprintln!("error: --seed requires a value"); + std::process::exit(1); + })); + } + other => { + eprintln!("error: unknown argument '{other}'"); + eprintln!("usage: trmt [-r|--rule ] [-s|--seed ]"); + eprintln!("note: quote rules with special characters: --rule 'R1>1,L0>2'"); + std::process::exit(1); + } + } + } + + (rule, seed) +} + fn run_app( terminal: &mut Terminal>, app: &mut App,