105 lines
3.1 KiB
Rust
105 lines
3.1 KiB
Rust
mod backup;
|
|
mod config;
|
|
mod run;
|
|
|
|
pub use crate::backup::MetaManager;
|
|
pub use crate::server::Metadata;
|
|
pub use backup::{BackupArgs, BackupCommands};
|
|
pub use run::RunCli;
|
|
|
|
use crate::backup::ManagerConfig;
|
|
use crate::server::ServerType;
|
|
use clap::{Args, Parser, Subcommand};
|
|
pub use config::Config;
|
|
use figment::{
|
|
providers::{Env, Format, Serialized, Toml},
|
|
Figment,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Subcommand)]
|
|
pub enum Commands {
|
|
/// Run the server
|
|
Run(RunCli),
|
|
/// Interact with the backup system without starting a server
|
|
Backup(BackupArgs),
|
|
}
|
|
|
|
#[derive(Args, Serialize, Deserialize, Clone)]
|
|
pub struct CliArgs {
|
|
/// Directory where configs are stored, and where the server will run
|
|
#[arg(long, value_name = "CONFIG_DIR", global = true)]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub config: Option<PathBuf>,
|
|
|
|
/// Directory where world files will be saved
|
|
#[arg(long, value_name = "WORLD_DIR", global = true)]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub world: Option<PathBuf>,
|
|
|
|
/// Directory where backups will be stored
|
|
#[arg(long, value_name = "BACKUP_DIR", global = true)]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub backup: Option<PathBuf>,
|
|
|
|
/// What backup layers to employ, provided as a list of tuples name,frequency,chains,chain_len
|
|
/// delimited by semicolons (;).
|
|
#[arg(long, global = true, value_delimiter = ';')]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub layers: Option<Vec<ManagerConfig>>,
|
|
|
|
/// Type of server
|
|
#[arg(long, global = true)]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub server: Option<ServerType>,
|
|
|
|
/// Version string for the server, e.g. 1.19.4-545
|
|
#[arg(long, global = true)]
|
|
#[serde(skip_serializing_if = "::std::option::Option::is_none")]
|
|
pub server_version: Option<String>,
|
|
}
|
|
|
|
#[derive(Parser, Serialize)]
|
|
#[command(author, version, about, long_about = None)]
|
|
pub struct Cli {
|
|
#[command(subcommand)]
|
|
#[serde(skip)]
|
|
pub command: Commands,
|
|
|
|
/// Path to a TOML configuration file
|
|
#[arg(long = "config-file", global = true)]
|
|
pub config_file: Option<PathBuf>,
|
|
|
|
#[command(flatten)]
|
|
pub args: CliArgs,
|
|
}
|
|
|
|
impl Cli {
|
|
pub fn run(&self) -> crate::Result<()> {
|
|
let config = self.config(&self.args)?;
|
|
|
|
match &self.command {
|
|
Commands::Run(args) => args.run(self, &config),
|
|
Commands::Backup(args) => Ok(args.run(&config)?),
|
|
}
|
|
}
|
|
|
|
pub fn config<T, U>(&self, args: &U) -> Result<T, figment::Error>
|
|
where
|
|
T: Default + Serialize + for<'de> Deserialize<'de>,
|
|
U: Serialize,
|
|
{
|
|
let toml_file = self
|
|
.config_file
|
|
.clone()
|
|
.unwrap_or(PathBuf::from(Env::var_or("ALEX_CONFIG_FILE", "")));
|
|
Figment::new()
|
|
.merge(Serialized::defaults(T::default()))
|
|
.merge(Toml::file(toml_file))
|
|
.merge(Env::prefixed("ALEX_"))
|
|
.merge(Serialized::defaults(args))
|
|
.extract()
|
|
}
|
|
}
|