Simplify arg parsing
This commit is contained in:
parent
28f1656c81
commit
e9e35c0dbe
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -175,6 +175,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"base64",
|
"base64",
|
||||||
"clap",
|
"clap",
|
||||||
|
"const_format",
|
||||||
"nom",
|
"nom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@ -188,6 +189,26 @@ dependencies = [
|
|||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_format"
|
||||||
|
version = "0.2.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b"
|
||||||
|
dependencies = [
|
||||||
|
"const_format_proc_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_format_proc_macros"
|
||||||
|
version = "0.2.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.13"
|
version = "0.5.13"
|
||||||
@ -782,6 +803,12 @@ version = "1.0.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -35,3 +35,4 @@ tracing = { version = "0.1.37", features = ["log"] }
|
|||||||
tracing-subscriber = { version = "0.3.17", features = ["tracing-log"] }
|
tracing-subscriber = { version = "0.3.17", features = ["tracing-log"] }
|
||||||
tracing-appender = "0.2.2"
|
tracing-appender = "0.2.2"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
|
const_format = "0.2.33"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use once_cell::sync::{Lazy, OnceCell};
|
use once_cell::sync::OnceCell;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::{fs::File, path::Path, path::PathBuf};
|
use std::{fs::File, path::Path, path::PathBuf};
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
@ -18,7 +17,8 @@ pub static CONFIG: OnceCell<Config> = OnceCell::new();
|
|||||||
/// The globablly-accessible static instance of Args.
|
/// The globablly-accessible static instance of Args.
|
||||||
/// On program startup, Args::load() should be called to initialize it.
|
/// On program startup, Args::load() should be called to initialize it.
|
||||||
pub static ARGS: OnceCell<Args> = OnceCell::new();
|
pub static ARGS: OnceCell<Args> = OnceCell::new();
|
||||||
static DEFAULT_ARGS: Lazy<Args> = Lazy::new(Args::default);
|
const DEFAULT_CONFIG_FILE: &str = "composition.toml";
|
||||||
|
const DEFAULT_LOG_DIR: &str = "logs";
|
||||||
|
|
||||||
/// Helper function to read a file from a `Path`
|
/// Helper function to read a file from a `Path`
|
||||||
/// and return its bytes as a `Vec<u8>`.
|
/// and return its bytes as a `Vec<u8>`.
|
||||||
@ -140,8 +140,8 @@ impl Default for GlobalConfig {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GlobalConfig {
|
GlobalConfig {
|
||||||
version: Config::get_formatted_version(Subcommand::None),
|
version: Config::get_formatted_version(Subcommand::None),
|
||||||
protocol_version: 762,
|
protocol_version: crate::PROTOCOL_VERSION,
|
||||||
game_version: "1.19.4".to_owned(),
|
game_version: crate::GAME_VERSION.to_owned(),
|
||||||
threads: None,
|
threads: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,9 +179,9 @@ pub struct Args {
|
|||||||
impl Default for Args {
|
impl Default for Args {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Args {
|
Args {
|
||||||
config_file: PathBuf::from("composition.toml"),
|
config_file: PathBuf::from(DEFAULT_CONFIG_FILE),
|
||||||
log_level: None,
|
log_level: None,
|
||||||
log_dir: PathBuf::from("logs"),
|
log_dir: PathBuf::from(DEFAULT_LOG_DIR),
|
||||||
subcommand: Subcommand::None,
|
subcommand: Subcommand::None,
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
server: None,
|
server: None,
|
||||||
@ -229,7 +229,7 @@ impl Args {
|
|||||||
.help("Configuration file path")
|
.help("Configuration file path")
|
||||||
.global(true)
|
.global(true)
|
||||||
.value_hint(clap::ValueHint::FilePath)
|
.value_hint(clap::ValueHint::FilePath)
|
||||||
.default_value(OsStr::new(&DEFAULT_ARGS.config_file)),
|
.default_value(DEFAULT_CONFIG_FILE),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("log-level")
|
Arg::new("log-level")
|
||||||
@ -248,7 +248,7 @@ impl Args {
|
|||||||
.global(true)
|
.global(true)
|
||||||
.value_name("dir")
|
.value_name("dir")
|
||||||
.value_hint(clap::ValueHint::DirPath)
|
.value_hint(clap::ValueHint::DirPath)
|
||||||
.default_value(OsStr::new(&DEFAULT_ARGS.log_dir)),
|
.default_value(DEFAULT_LOG_DIR),
|
||||||
);
|
);
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,9 @@ use config::Subcommand;
|
|||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
pub const PROTOCOL_VERSION: i32 = 762;
|
||||||
|
pub const GAME_VERSION: &str = "1.19.4";
|
||||||
|
|
||||||
/// A globally accessible instant of the composition's start time.
|
/// A globally accessible instant of the composition's start time.
|
||||||
///
|
///
|
||||||
/// This should be set immediately on startup.
|
/// This should be set immediately on startup.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::config::{Args, Config};
|
use crate::config::{Args, Config};
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ffi::OsStr;
|
|
||||||
|
|
||||||
pub static DEFAULT_PROXY_ARGS: Lazy<ProxyArgs> = Lazy::new(ProxyArgs::default);
|
const DEFAULT_PORT: u16 = 25566;
|
||||||
|
const DEFAULT_UPSTREAM_HOST: &str = "127.0.0.1";
|
||||||
|
const DEFAULT_UPSTREAM_PORT: u16 = 25565;
|
||||||
|
|
||||||
/// The main server configuration struct.
|
/// The main server configuration struct.
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
@ -14,14 +14,16 @@ pub struct ProxyConfig {
|
|||||||
#[serde(rename = "version-string")]
|
#[serde(rename = "version-string")]
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub upstream: String,
|
pub upstream_host: String,
|
||||||
|
pub upstream_port: u16,
|
||||||
}
|
}
|
||||||
impl Default for ProxyConfig {
|
impl Default for ProxyConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ProxyConfig {
|
ProxyConfig {
|
||||||
version: Config::get_formatted_version(crate::config::Subcommand::Proxy),
|
version: Config::get_formatted_version(crate::config::Subcommand::Proxy),
|
||||||
port: 25565,
|
port: DEFAULT_PORT,
|
||||||
upstream: String::new(),
|
upstream_host: DEFAULT_UPSTREAM_HOST.to_owned(),
|
||||||
|
upstream_port: DEFAULT_UPSTREAM_PORT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,16 +32,27 @@ impl ProxyConfig {
|
|||||||
&Config::instance().proxy
|
&Config::instance().proxy
|
||||||
}
|
}
|
||||||
pub fn load_args(&mut self) {
|
pub fn load_args(&mut self) {
|
||||||
self.upstream = ProxyArgs::instance()
|
self.upstream_host = ProxyArgs::instance()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p.upstream.clone())
|
.map(|p| p.upstream_host.clone())
|
||||||
.unwrap_or(DEFAULT_PROXY_ARGS.upstream.clone());
|
.unwrap_or(DEFAULT_UPSTREAM_HOST.to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
pub struct ProxyArgs {
|
pub struct ProxyArgs {
|
||||||
upstream: String,
|
port: u16,
|
||||||
|
upstream_host: String,
|
||||||
|
upstream_port: u16,
|
||||||
|
}
|
||||||
|
impl Default for ProxyArgs {
|
||||||
|
fn default() -> Self {
|
||||||
|
ProxyArgs {
|
||||||
|
port: DEFAULT_PORT,
|
||||||
|
upstream_host: DEFAULT_UPSTREAM_HOST.to_owned(),
|
||||||
|
upstream_port: DEFAULT_UPSTREAM_PORT,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl ProxyArgs {
|
impl ProxyArgs {
|
||||||
pub fn instance() -> Option<&'static Self> {
|
pub fn instance() -> Option<&'static Self> {
|
||||||
@ -49,20 +62,40 @@ impl ProxyArgs {
|
|||||||
clap::Command::new("proxy")
|
clap::Command::new("proxy")
|
||||||
.about("Run composition in proxy mode")
|
.about("Run composition in proxy mode")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("upstream")
|
Arg::new("port")
|
||||||
.short('u')
|
.short('p')
|
||||||
.long("upstream")
|
.long("port")
|
||||||
|
.help("Proxy listening port")
|
||||||
|
.value_hint(clap::ValueHint::Other)
|
||||||
|
.default_value(const_format::formatcp!("{}", DEFAULT_PORT)),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("upstream-host")
|
||||||
|
.short('U')
|
||||||
|
.long("upstream-host")
|
||||||
.help("Upstream server address")
|
.help("Upstream server address")
|
||||||
.value_hint(clap::ValueHint::Hostname)
|
.value_hint(clap::ValueHint::Hostname)
|
||||||
.default_value(OsStr::new(&DEFAULT_PROXY_ARGS.upstream)),
|
.default_value(const_format::formatcp!("{}", DEFAULT_UPSTREAM_HOST)),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("upstream-port")
|
||||||
|
.short('P')
|
||||||
|
.long("upstream-port")
|
||||||
|
.help("Upstream server port")
|
||||||
|
.value_hint(clap::ValueHint::Other)
|
||||||
|
.default_value(const_format::formatcp!("{}", DEFAULT_UPSTREAM_PORT)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn parse(m: clap::ArgMatches) -> Self {
|
pub fn parse(m: clap::ArgMatches) -> Self {
|
||||||
let mut proxy_args = ProxyArgs::default();
|
let mut proxy_args = ProxyArgs::default();
|
||||||
proxy_args.upstream = m
|
proxy_args.port = *m.get_one::<u16>("port").unwrap_or(&proxy_args.port);
|
||||||
.get_one::<String>("upstream")
|
proxy_args.upstream_host = m
|
||||||
.unwrap_or(&proxy_args.upstream)
|
.get_one::<String>("upstream-host")
|
||||||
|
.unwrap_or(&proxy_args.upstream_host)
|
||||||
.clone();
|
.clone();
|
||||||
|
proxy_args.upstream_port = *m
|
||||||
|
.get_one::<u16>("upstream-port")
|
||||||
|
.unwrap_or(&proxy_args.upstream_port);
|
||||||
proxy_args
|
proxy_args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,10 @@ impl Proxy {
|
|||||||
"Done! Start took {:?}",
|
"Done! Start took {:?}",
|
||||||
crate::START_TIME.get().unwrap().elapsed()
|
crate::START_TIME.get().unwrap().elapsed()
|
||||||
);
|
);
|
||||||
info!("Upstream server: {}", config.proxy.upstream);
|
info!(
|
||||||
|
"Upstream server: {}:{}",
|
||||||
|
config.proxy.upstream_host, config.proxy.upstream_port
|
||||||
|
);
|
||||||
|
|
||||||
// Spawn the ctrl-c task.
|
// Spawn the ctrl-c task.
|
||||||
let r = running.clone();
|
let r = running.clone();
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use crate::config::{read_file, Args, Config};
|
use crate::config::{read_file, Args, Config};
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::{fs::File, path::Path, path::PathBuf};
|
use std::{fs::File, path::Path, path::PathBuf};
|
||||||
use tracing::{error, trace, warn};
|
use tracing::{error, trace, warn};
|
||||||
|
|
||||||
pub static DEFAULT_SERVER_ARGS: Lazy<ServerArgs> = Lazy::new(ServerArgs::default);
|
const DEFAULT_SERVER_ICON: &str = "server-icon.png";
|
||||||
|
|
||||||
/// The main server configuration struct.
|
/// The main server configuration struct.
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
@ -30,7 +28,7 @@ impl Default for ServerConfig {
|
|||||||
port: 25565,
|
port: 25565,
|
||||||
max_players: 20,
|
max_players: 20,
|
||||||
motd: "Hello world!".to_owned(),
|
motd: "Hello world!".to_owned(),
|
||||||
server_icon: PathBuf::from("server-icon.png"),
|
server_icon: PathBuf::from(DEFAULT_SERVER_ICON),
|
||||||
server_icon_bytes: include_bytes!("../server-icon.png").to_vec(),
|
server_icon_bytes: include_bytes!("../server-icon.png").to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +41,7 @@ impl ServerConfig {
|
|||||||
self.server_icon = ServerArgs::instance()
|
self.server_icon = ServerArgs::instance()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|s| s.server_icon.clone())
|
.map(|s| s.server_icon.clone())
|
||||||
.unwrap_or(DEFAULT_SERVER_ARGS.server_icon.clone());
|
.unwrap_or(PathBuf::from(DEFAULT_SERVER_ICON));
|
||||||
self.load_icon();
|
self.load_icon();
|
||||||
}
|
}
|
||||||
/// Load the server icon.
|
/// Load the server icon.
|
||||||
@ -87,9 +85,8 @@ pub struct ServerArgs {
|
|||||||
}
|
}
|
||||||
impl Default for ServerArgs {
|
impl Default for ServerArgs {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let config = Config::default();
|
|
||||||
ServerArgs {
|
ServerArgs {
|
||||||
server_icon: config.server.server_icon,
|
server_icon: PathBuf::from(DEFAULT_SERVER_ICON),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +102,7 @@ impl ServerArgs {
|
|||||||
.long("server-icon")
|
.long("server-icon")
|
||||||
.help("Server icon file path")
|
.help("Server icon file path")
|
||||||
.value_hint(clap::ValueHint::FilePath)
|
.value_hint(clap::ValueHint::FilePath)
|
||||||
.default_value(OsStr::new(&DEFAULT_SERVER_ARGS.server_icon)),
|
.default_value(DEFAULT_SERVER_ICON),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn parse(m: clap::ArgMatches) -> Self {
|
pub fn parse(m: clap::ArgMatches) -> Self {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user