feat: cli base

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2025-10-13 13:48:49 +01:00
parent 4e1d105787
commit 73c75f941a
13 changed files with 1426 additions and 0 deletions

19
src/cli/backup.rs Normal file
View File

@@ -0,0 +1,19 @@
use super::common::file::{Input, Output};
use clap::Subcommand;
#[derive(Subcommand, Debug)]
pub enum BackupCmd {
/// Export backup
#[command(alias = "e")]
Export {
/// Output file (use '-' to write to stdout)
output_file: Output,
},
/// Import backup
#[command(alias = "i")]
Import {
/// Input file (use '-' to read from stdin)
input_file: Input,
},
}

35
src/cli/common/file.rs Normal file
View File

@@ -0,0 +1,35 @@
use std::{error::Error, path::PathBuf, str::FromStr};
#[derive(Debug, Clone)]
pub enum Input {
Path(PathBuf),
Stdin,
}
impl FromStr for Input {
type Err = Box<dyn Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "-" {
Ok(Input::Stdin)
} else {
Ok(Input::Path(PathBuf::from(s)))
}
}
}
#[derive(Debug, Clone)]
pub enum Output {
Path(PathBuf),
Stdout,
}
impl FromStr for Output {
type Err = Box<dyn Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "-" {
Ok(Output::Stdout)
} else {
Ok(Output::Path(PathBuf::from(s)))
}
}
}

28
src/cli/common/film.rs Normal file
View File

@@ -0,0 +1,28 @@
use std::error::Error;
use clap::Args;
#[derive(Debug, Clone)]
pub enum SimulationSelector {
Slot(u8),
Name(String),
}
impl std::str::FromStr for SimulationSelector {
type Err = Box<dyn Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(slot) = s.parse::<u8>() {
return Ok(SimulationSelector::Slot(slot));
}
if s.is_empty() {
Err("Simulation name cannot be empty".into())
} else {
Ok(SimulationSelector::Name(s.to_string()))
}
}
}
#[derive(Args, Debug)]
pub struct FilmSimulationOptions {}

2
src/cli/common/mod.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod file;
pub mod film;

12
src/cli/device.rs Normal file
View File

@@ -0,0 +1,12 @@
use clap::Subcommand;
#[derive(Subcommand, Debug)]
pub enum DeviceCmd {
/// List devices
#[command(alias = "l")]
List,
/// Dump device info
#[command(alias = "i")]
Info,
}

55
src/cli/mod.rs Normal file
View File

@@ -0,0 +1,55 @@
mod backup;
mod common;
mod device;
mod render;
mod simulation;
use clap::{Parser, Subcommand};
use backup::BackupCmd;
use device::DeviceCmd;
use render::RenderCmd;
use simulation::SimulationCmd;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None, author)]
pub struct Cli {
/// Subcommands
#[command(subcommand)]
pub command: Commands,
/// Format output using json
#[arg(long, short = 'j', global = true)]
pub json: bool,
/// Only log warnings and errors
#[arg(long, short = 'q', global = true, conflicts_with = "verbose")]
pub quiet: bool,
/// Log extra debugging information
#[arg(long, short = 'v', global = true, conflicts_with = "quiet")]
pub verbose: bool,
/// Manually specify target device
#[arg(long, short = 'd', global = true)]
pub device: Option<String>,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
/// Manage devices
#[command(alias = "d", subcommand)]
Device(DeviceCmd),
/// Manage film simulations
#[command(alias = "s", subcommand)]
Simulation(SimulationCmd),
/// Manage backups
#[command(alias = "b", subcommand)]
Backup(BackupCmd),
/// Render images
#[command(alias = "r")]
Render(RenderCmd),
}

27
src/cli/render.rs Normal file
View File

@@ -0,0 +1,27 @@
use std::path::PathBuf;
use super::common::{
file::{Input, Output},
film::{FilmSimulationOptions, SimulationSelector},
};
use clap::Args;
#[derive(Args, Debug)]
pub struct RenderCmd {
/// Simulation number or name
#[arg(long, conflicts_with = "simulation_file")]
simulation: Option<SimulationSelector>,
/// Path to exported simulation
#[arg(long, conflicts_with = "simulation")]
simulation_file: Option<PathBuf>,
#[command(flatten)]
film_simulation_options: FilmSimulationOptions,
/// RAF input file (use '-' to read from stdin)
input: Input,
/// Output file (use '-' to write to stdout)
output: Output,
}

49
src/cli/simulation.rs Normal file
View File

@@ -0,0 +1,49 @@
use super::common::{
file::{Input, Output},
film::{FilmSimulationOptions, SimulationSelector},
};
use clap::Subcommand;
#[derive(Subcommand, Debug)]
pub enum SimulationCmd {
/// List simulations
#[command(alias = "l")]
List,
/// Get simulation
#[command(alias = "g")]
Get {
/// Simulation number or name
simulation: SimulationSelector,
},
/// Set simulation parameters
#[command(alias = "s")]
Set {
/// Simulation number or name
simulation: SimulationSelector,
#[command(flatten)]
film_simulation_options: FilmSimulationOptions,
},
/// Export simulation
#[command(alias = "e")]
Export {
/// Simulation number or name
simulation: SimulationSelector,
/// Output file (use '-' to write to stdout)
output_file: Output,
},
/// Import simulation
#[command(alias = "i")]
Import {
/// Simulation number
slot: u8,
/// Input file (use '-' to read from stdin)
input_file: Input,
},
}