mod commands;
mod dispatch;
mod reexec;
mod value_enums;
use clap::Parser;
use commands::{EditorArgs, RenderArgs};
pub(crate) use commands::Commands;
const BANNER: &str = r#"
______
/ ____/___ ____ ___________ ____ __________ __
/ / / __ \/ __ \/ ___/ / __ \/ __ \/ /_ __/ / / /
/ /___/ /_/ / / / / /__/ / / / / / / / / / / / /_/ /
\____/\____/_/ /_/\___/_/_/ /_/_/ /_/_/ /_/ \__, /
/____/"#;
pub struct Invocation(Cli);
impl Invocation {
pub fn from_args() -> Self {
let cli = Cli::parse();
reexec::reexec_with_metal_validation(&cli);
Self(cli)
}
pub fn dispatch(&self, tree: &concinnity_engine::StateTree) -> std::io::Result<()> {
dispatch::dispatch(&self.0, tree)
}
}
#[derive(Parser, Debug)]
#[command(name = "concinnity")]
#[command(about = BANNER, long_about = None)]
#[command(version = crate::command::version_details(), disable_version_flag = true)]
pub(crate) struct Cli {
#[command(subcommand)]
pub(crate) command: Option<Commands>,
#[arg(short = 'V', short_alias = 'v', long, action = clap::ArgAction::Version)]
pub(crate) version: (),
}
static DEFAULT_COMMAND: Commands = Commands::Editor(EditorArgs {
file: None,
debug_port: None,
validation: None,
render: RenderArgs {
quality_preset: None,
rt_dynamic: None,
rt_skinned_geometry: None,
dlss_preset: None,
fixed_frame_rate: None,
hide: Vec::new(),
},
});
impl Cli {
pub(crate) fn resolved_command(&self) -> &Commands {
self.command.as_ref().unwrap_or(&DEFAULT_COMMAND)
}
}
#[cfg(test)]
mod tests {
use super::*;
use clap::CommandFactory;
#[test]
fn cli_config_is_valid() {
Cli::command().debug_assert();
}
#[test]
fn a_bare_invocation_runs_the_editor() {
let cli = Cli::try_parse_from(["concinnity"]).unwrap();
assert!(cli.command.is_none());
let Commands::Editor(a) = cli.resolved_command() else {
panic!("expected the editor by default");
};
assert!(a.file.is_none());
assert!(a.debug_port.is_none());
assert!(a.validation.is_none());
assert!(a.render.quality_preset.is_none());
assert!(a.render.rt_dynamic.is_none());
assert!(a.render.rt_skinned_geometry.is_none());
assert!(a.render.dlss_preset.is_none());
}
#[test]
fn an_unknown_subcommand_is_still_an_error() {
assert!(Cli::try_parse_from(["concinnity", "edtior"]).is_err());
}
}