cli: add subcommand support

This commit is contained in:
Schrottkatze 2024-02-19 17:54:40 +01:00
parent 1e9648966f
commit 56ec11e143
No known key found for this signature in database
3 changed files with 42 additions and 29 deletions

View file

@ -1,18 +1,11 @@
use std::path::PathBuf; use self::config_file::{find_config_file, Configs};
pub(crate) use cli::CliConfigs;
use clap::Parser;
use self::{
cli::Args,
config_file::{find_config_file, Configs},
};
mod cli; mod cli;
mod config_file; mod config_file;
/// this struct may hold all configuration /// this struct may hold all configuration
pub struct Config { pub struct Config {
pub source: PathBuf,
pub evaluator: eval::Available, pub evaluator: eval::Available,
pub startup_msg: bool, pub startup_msg: bool,
@ -20,10 +13,9 @@ pub struct Config {
impl Config { impl Config {
/// Get the configs from all possible places (args, file, env...) /// Get the configs from all possible places (args, file, env...)
pub fn read() -> Self { pub fn read(args: &CliConfigs) -> Self {
let args = Args::parse(); let config = if let Some(config) = &args.config_path {
let config = if let Some(config) = args.config_path { Ok(config.clone())
Ok(config)
} else { } else {
find_config_file() find_config_file()
}; };
@ -42,7 +34,6 @@ impl Config {
if let Some(file) = config { if let Some(file) = config {
Self { Self {
source: args.source,
evaluator: args.evaluator.and(file.evaluator).unwrap_or_default(), evaluator: args.evaluator.and(file.evaluator).unwrap_or_default(),
// this is negated because to an outward api, the negative is more intuitive, // this is negated because to an outward api, the negative is more intuitive,
// while in the source the other way around is more intuitive // while in the source the other way around is more intuitive
@ -50,7 +41,6 @@ impl Config {
} }
} else { } else {
Self { Self {
source: args.source,
startup_msg: !args.no_startup_message, startup_msg: !args.no_startup_message,
evaluator: args.evaluator.unwrap_or_default(), evaluator: args.evaluator.unwrap_or_default(),
} }

View file

@ -1,12 +1,9 @@
use std::path::PathBuf; use std::path::PathBuf;
use clap::{builder::BoolishValueParser, ArgAction, Parser}; use clap::{builder::BoolishValueParser, ArgAction, Args};
#[derive(Parser)]
pub(crate) struct Args {
/// What file contains the pipeline to evaluate.
pub source: PathBuf,
#[derive(Args)]
pub(crate) struct CliConfigs {
/// How to actually run the pipeline. /// How to actually run the pipeline.
/// Overrides the config file. Defaults to the debug evaluator. /// Overrides the config file. Defaults to the debug evaluator.
#[arg(short, long)] #[arg(short, long)]

View file

@ -1,6 +1,7 @@
use std::fs; use std::{fs, path::PathBuf};
use config::Config; use clap::{Parser, Subcommand};
use config::{CliConfigs, Config};
use welcome_msg::print_startup_msg; use welcome_msg::print_startup_msg;
mod config; mod config;
@ -9,19 +10,44 @@ mod config;
mod error_reporting; mod error_reporting;
mod welcome_msg; mod welcome_msg;
#[derive(Parser)]
struct Args {
#[command(flatten)]
configs: CliConfigs,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Run {
/// What file contains the pipeline to evaluate.
source: PathBuf,
},
Dev,
}
fn main() { fn main() {
// TODO: proper error handling across the whole function // TODO: proper error handling across the whole function
// don't forget to also look inside `Config` // don't forget to also look inside `Config`
let cfg = Config::read(); let args = Args::parse();
let cfg = Config::read(&args.configs);
if cfg.startup_msg { if cfg.startup_msg {
print_startup_msg(); print_startup_msg();
} }
let source = fs::read_to_string(cfg.source).expect("can't find source file"); match args.command {
Commands::Run { source } => {
let source = fs::read_to_string(source).expect("can't find source file");
let ir = ir::from_ron(&source).expect("failed to parse source to graph ir"); let ir = ir::from_ron(&source).expect("failed to parse source to graph ir");
let mut machine = cfg.evaluator.pick(); let mut machine = cfg.evaluator.pick();
machine.feed(ir); machine.feed(ir);
machine.eval_full(); machine.eval_full();
}
Commands::Dev => {
println!("Hello world!");
}
}
} }