grapevine/src/cli.rs
2024-09-26 20:55:35 -07:00

99 lines
2.4 KiB
Rust

//! Integration with `clap`
//!
//! CLI argument structs are defined in this module. Execution logic for each
//! command goes in a submodule.
use std::path::PathBuf;
use clap::{Parser, Subcommand};
use crate::{config::DatabaseBackend, error};
mod db;
mod serve;
/// Command line arguments
#[derive(Parser)]
#[clap(
about,
version = crate::version(),
)]
pub(crate) struct Args {
#[clap(subcommand)]
pub(crate) command: Command,
}
#[derive(Subcommand)]
pub(crate) enum Command {
/// Run the server.
Serve(ServeArgs),
/// Database utilities
#[clap(subcommand)]
Db(DbCommand),
}
/// Wrapper for the `--config` arg.
///
/// This exists to centralize the `mut_arg` code that sets the help value based
/// on runtime information.
#[derive(clap::Args)]
#[clap(mut_arg("config", |x| {
let help = "Set the path to the configuration file";
x.help(help).long_help(format!(
"{}\n\nIf this option is specified, the provided value is used \
as-is.\n\nIf this option is not specified, then the XDG Base \
Directory Specification is followed, searching for the path `{}` \
in the configuration directories.
",
help,
crate::config::DEFAULT_PATH.display(),
))
}))]
pub(crate) struct ConfigArg {
/// Path to the configuration file
#[clap(long, short)]
pub(crate) config: Option<PathBuf>,
}
#[derive(clap::Args)]
pub(crate) struct ServeArgs {
#[clap(flatten)]
pub(crate) config: ConfigArg,
}
#[derive(Subcommand)]
pub(crate) enum DbCommand {
/// Convert between database backends
///
/// Once this command successfully completes, copy or move the `media`
/// directory from `IN_PATH` to `OUT_PATH` to complete the migration.
Convert(DbConvert),
}
#[derive(clap::Args)]
pub(crate) struct DbConvert {
/// The backend to convert from
in_backend: DatabaseBackend,
/// The backend to convert to
out_backend: DatabaseBackend,
/// Path to the database to read
in_path: PathBuf,
/// Path to write the new database
out_path: PathBuf,
}
impl Args {
pub(crate) async fn run(self) -> Result<(), error::Main> {
match self.command {
Command::Serve(args) => serve::run(args).await?,
Command::Db(DbCommand::Convert(args)) => {
db::convert::run(args).await?
}
}
Ok(())
}
}