alex/src/cli.rs

165 lines
4.4 KiB
Rust

use crate::server::ServerType;
use clap::{Args, Parser, Subcommand};
use std::error::Error;
use std::fmt;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Clone, Debug)]
pub struct ManagerConfig {
name: String,
frequency: u32,
chain_len: u64,
chains: u64,
}
#[derive(Debug)]
pub struct ParseManagerConfigErr;
impl Error for ParseManagerConfigErr {}
impl fmt::Display for ParseManagerConfigErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "parse manager config err")
}
}
impl FromStr for ManagerConfig {
type Err = ParseManagerConfigErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let splits: Vec<&str> = s.split(',').collect();
if let [name, frequency, chains, chain_len] = splits[..] {
let name: String = name.parse().map_err(|_| ParseManagerConfigErr)?;
let frequency: u32 = frequency.parse().map_err(|_| ParseManagerConfigErr)?;
let chains: u64 = chains.parse().map_err(|_| ParseManagerConfigErr)?;
let chain_len: u64 = chain_len.parse().map_err(|_| ParseManagerConfigErr)?;
Ok(ManagerConfig {
name,
chains,
chain_len,
frequency,
})
} else {
Err(ParseManagerConfigErr)
}
}
}
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
/// Directory where configs are stored, and where the server will run
#[arg(
long,
value_name = "CONFIG_DIR",
default_value = ".",
env = "ALEX_CONFIG_DIR",
global = true
)]
pub config: PathBuf,
/// Directory where world files will be saved
#[arg(
long,
value_name = "WORLD_DIR",
default_value = "../worlds",
env = "ALEX_WORLD_DIR",
global = true
)]
pub world: PathBuf,
/// Directory where backups will be stored
#[arg(
long,
value_name = "BACKUP_DIR",
default_value = "../backups",
env = "ALEX_BACKUP_DIR",
global = true
)]
pub backup: PathBuf,
/// What backup layers to employ, provided as a list of tuples name,frequency,chain_len,chains
/// delimited by semicolons (;).
#[arg(long, env = "ALEX_LAYERS", global = true, value_delimiter = ';')]
pub layers: Vec<ManagerConfig>,
/// Length of a backup chain
#[arg(
short = 'l',
long,
default_value_t = 4,
env = "ALEX_CHAIN_LEN",
global = true
)]
pub chain_len: u64,
/// How many backup chains to keep
#[arg(
short = 'n',
long,
default_value_t = 7,
env = "ALEX_CHAINS",
global = true
)]
pub chains: u64,
/// How frequently to perform a backup, in minutes; 0 to disable.
#[arg(
short = 't',
long,
default_value_t = 0,
env = "ALEX_FREQUENCY",
global = true
)]
pub frequency: u32,
/// Type of server
#[arg(long, default_value = "unknown", env = "ALEX_SERVER", global = true)]
pub server: ServerType,
/// Version string for the server, e.g. 1.19.4-545
#[arg(long, default_value = "", env = "ALEX_SERVER_VERSION", global = true)]
pub server_version: String,
}
#[derive(Subcommand)]
pub enum Commands {
/// Run the server
Run(RunArgs),
/// Create a new backup of the server. This command should only be used when the server is not
/// running.
Backup(BackupArgs),
}
#[derive(Args)]
pub struct RunArgs {
/// Server jar to execute
#[arg(
long,
value_name = "JAR_PATH",
default_value = "server.jar",
env = "ALEX_JAR"
)]
pub jar: PathBuf,
/// Java command to run the server jar with
#[arg(long, value_name = "JAVA_CMD", default_value_t = String::from("java"), env = "ALEX_JAVA")]
pub java: String,
/// XMS value in megabytes for the server instance
#[arg(long, default_value_t = 1024, env = "ALEX_XMS")]
pub xms: u64,
/// XMX value in megabytes for the server instance
#[arg(long, default_value_t = 2048, env = "ALEX_XMX")]
pub xmx: u64,
/// Don't actually run the server, but simply output the server configuration that would have
/// been ran
#[arg(short, long, default_value_t = false)]
pub dry: bool,
}
#[derive(Args)]
pub struct BackupArgs {}