feat: add help and version flags to argument parser
This commit is contained in:
parent
69475d098c
commit
01be9152a7
5 changed files with 202 additions and 46 deletions
100
Cargo.lock
generated
100
Cargo.lock
generated
|
|
@ -184,6 +184,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.97"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "apply"
|
name = "apply"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -844,6 +850,12 @@ dependencies = [
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "5.4.0"
|
version = "5.4.0"
|
||||||
|
|
@ -1070,6 +1082,7 @@ dependencies = [
|
||||||
name = "cosmic-player"
|
name = "cosmic-player"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap_lex",
|
||||||
"dirs",
|
"dirs",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"fork",
|
"fork",
|
||||||
|
|
@ -1084,13 +1097,13 @@ dependencies = [
|
||||||
"libcosmic",
|
"libcosmic",
|
||||||
"log",
|
"log",
|
||||||
"mpris-server",
|
"mpris-server",
|
||||||
"pico-args",
|
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"smol_str",
|
"smol_str",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
|
"vergen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1292,6 +1305,15 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
|
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derivative"
|
name = "derivative"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|
@ -3680,6 +3702,12 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.46"
|
version = "0.1.46"
|
||||||
|
|
@ -3752,6 +3780,15 @@ dependencies = [
|
||||||
"syn 2.0.96",
|
"syn 2.0.96",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc"
|
name = "objc"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
|
@ -4139,6 +4176,12 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
|
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
|
|
@ -4561,6 +4604,12 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustybuzz"
|
name = "rustybuzz"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -4796,9 +4845,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-client-toolkit"
|
name = "smithay-client-toolkit"
|
||||||
|
|
@ -5138,6 +5187,39 @@ dependencies = [
|
||||||
"weezl",
|
"weezl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num-conv",
|
||||||
|
"num_threads",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-keccak"
|
name = "tiny-keccak"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
|
@ -5575,6 +5657,18 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vergen"
|
||||||
|
version = "8.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cfg-if",
|
||||||
|
"rustversion",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
|
||||||
12
Cargo.toml
12
Cargo.toml
|
|
@ -3,6 +3,9 @@ name = "cosmic-player"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
vergen = { version = "8", features = ["git", "gitcl"] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dirs = "5"
|
dirs = "5"
|
||||||
gstreamer-tag = "0.23"
|
gstreamer-tag = "0.23"
|
||||||
|
|
@ -12,11 +15,15 @@ serde = { version = "1", features = ["serde_derive"] }
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
tokio = "1"
|
tokio = "1"
|
||||||
url = "2"
|
url = "2"
|
||||||
pico-args = "0.5"
|
# CLI arguments
|
||||||
|
clap_lex = "0.7"
|
||||||
# Internationalization
|
# Internationalization
|
||||||
icu_collator = "1.5"
|
icu_collator = "1.5"
|
||||||
icu_provider = { version = "1.5", features = ["sync"] }
|
icu_provider = { version = "1.5", features = ["sync"] }
|
||||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
i18n-embed = { version = "0.14", features = [
|
||||||
|
"fluent-system",
|
||||||
|
"desktop-requester",
|
||||||
|
] }
|
||||||
i18n-embed-fl = "0.7"
|
i18n-embed-fl = "0.7"
|
||||||
rust-embed = "8"
|
rust-embed = "8"
|
||||||
# Logging
|
# Logging
|
||||||
|
|
@ -61,4 +68,3 @@ debug = true
|
||||||
# libcosmic = { path = "../libcosmic" }
|
# libcosmic = { path = "../libcosmic" }
|
||||||
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
# cosmic-config = { path = "../libcosmic/cosmic-config" }
|
||||||
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }
|
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }
|
||||||
|
|
||||||
|
|
|
||||||
6
build.rs
Normal file
6
build.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
use vergen::EmitBuilder;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
EmitBuilder::builder().git_sha(true).emit().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
114
src/argparse.rs
114
src/argparse.rs
|
|
@ -3,9 +3,57 @@
|
||||||
|
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
|
||||||
|
use clap_lex::RawArgs;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn parse() -> Arguments {
|
||||||
|
let raw_args = RawArgs::from_args();
|
||||||
|
let mut cursor = raw_args.cursor();
|
||||||
|
let mut arguments = Arguments::default();
|
||||||
|
let mut urls = Vec::new();
|
||||||
|
|
||||||
|
// Parse the arguments
|
||||||
|
while let Some(arg) = raw_args.next(&mut cursor) {
|
||||||
|
if let Some(mut shorts) = arg.to_short() {
|
||||||
|
while let Some(short) = shorts.next_flag() {
|
||||||
|
match short {
|
||||||
|
Ok('h') => print_help(),
|
||||||
|
Ok('V') => print_version(),
|
||||||
|
Ok(c) => warn!("unexpected flag: -{c}"),
|
||||||
|
Err(os_str) => warn!("unexpected flag: -{}", os_str.to_string_lossy()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let Some((long, _opt_value)) = arg.to_long() {
|
||||||
|
match long {
|
||||||
|
Ok("help") => print_help(),
|
||||||
|
Ok("version") => print_version(),
|
||||||
|
_ => warn!("unexpected flag: {}", arg.display()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Freestanding arguments are treated as URLs
|
||||||
|
match arg.to_value().ok().map(Source::try_from) {
|
||||||
|
Some(Ok(source)) => urls.push(source.0),
|
||||||
|
Some(Err(why)) => {
|
||||||
|
warn!("{}: not a valid URL: {}", arg.display(), why)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
warn!("{}: not a valid string", arg.display())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if urls.len() > 1 {
|
||||||
|
arguments.urls = Some(urls);
|
||||||
|
} else {
|
||||||
|
urls.truncate(1);
|
||||||
|
arguments.url_opt = urls.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Arguments {
|
pub struct Arguments {
|
||||||
/// Files or directory URLs to play
|
/// Files or directory URLs to play
|
||||||
|
|
@ -14,39 +62,6 @@ pub struct Arguments {
|
||||||
pub url_opt: Option<Url>,
|
pub url_opt: Option<Url>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arguments {
|
|
||||||
pub fn from_args() -> Result<Self, pico_args::Error> {
|
|
||||||
let mut parser = pico_args::Arguments::from_env();
|
|
||||||
|
|
||||||
// Freestanding arguments are treated as URLs
|
|
||||||
let urls: Vec<Url> = std::iter::from_fn(|| {
|
|
||||||
parser
|
|
||||||
.opt_free_from_fn(|arg| Source::try_from(arg))
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
})
|
|
||||||
.map(|source| source.0)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let remainder = parser.finish();
|
|
||||||
for arg in remainder {
|
|
||||||
warn!("Unused argument: {arg:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if urls.len() > 1 {
|
|
||||||
Ok(Arguments {
|
|
||||||
urls: Some(urls),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Ok(Arguments {
|
|
||||||
url_opt: urls.into_iter().next(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[derive(Debug)]
|
// #[derive(Debug)]
|
||||||
// pub enum Source {
|
// pub enum Source {
|
||||||
// File(Url),
|
// File(Url),
|
||||||
|
|
@ -81,3 +96,36 @@ impl TryFrom<&str> for Source {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
pub fn print_help() -> ! {
|
||||||
|
let version = env!("CARGO_PKG_VERSION");
|
||||||
|
let git_rev = env!("VERGEN_GIT_SHA");
|
||||||
|
|
||||||
|
println!(
|
||||||
|
r#"cosmic-player {version} (git commit {git_rev})
|
||||||
|
System76 <info@system76.com>
|
||||||
|
|
||||||
|
Designed for the COSMIC™ desktop environment, cosmic-player is a
|
||||||
|
libcosmic-based multimedia player for music and videos.
|
||||||
|
|
||||||
|
Project home page: https://github.com/pop-os/cosmic-player
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Show this message
|
||||||
|
-V, --version Show the version of cosmic-player"#
|
||||||
|
);
|
||||||
|
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
pub fn print_version() -> ! {
|
||||||
|
println!(
|
||||||
|
"cosmic-player {} (git commit {})",
|
||||||
|
env!("CARGO_PKG_VERSION"),
|
||||||
|
env!("VERGEN_GIT_SHA")
|
||||||
|
);
|
||||||
|
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
|
||||||
16
src/main.rs
16
src/main.rs
|
|
@ -52,6 +52,8 @@ const GST_PLAY_FLAG_VIDEO: i32 = 1 << 0;
|
||||||
const GST_PLAY_FLAG_AUDIO: i32 = 1 << 1;
|
const GST_PLAY_FLAG_AUDIO: i32 = 1 << 1;
|
||||||
const GST_PLAY_FLAG_TEXT: i32 = 1 << 2;
|
const GST_PLAY_FLAG_TEXT: i32 = 1 << 2;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
fn language_name(code: &str) -> Option<String> {
|
fn language_name(code: &str) -> Option<String> {
|
||||||
let code_c = CString::new(code).ok()?;
|
let code_c = CString::new(code).ok()?;
|
||||||
let name_c = unsafe {
|
let name_c = unsafe {
|
||||||
|
|
@ -68,7 +70,7 @@ fn language_name(code: &str) -> Option<String> {
|
||||||
|
|
||||||
/// Runs application with these settings
|
/// Runs application with these settings
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
#[cfg(all(unix, not(target_os = "redox")))]
|
#[cfg(all(unix, not(target_os = "redox")))]
|
||||||
match fork::daemon(true, true) {
|
match fork::daemon(true, true) {
|
||||||
Ok(fork::Fork::Child) => (),
|
Ok(fork::Fork::Child) => (),
|
||||||
|
|
@ -78,17 +80,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
|
||||||
|
|
||||||
localize::localize();
|
localize::localize();
|
||||||
|
|
||||||
|
let args = argparse::parse();
|
||||||
|
|
||||||
let (config_handler, config) = match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) {
|
let (config_handler, config) = match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) {
|
||||||
Ok(config_handler) => {
|
Ok(config_handler) => {
|
||||||
let config = match Config::get_entry(&config_handler) {
|
let config = match Config::get_entry(&config_handler) {
|
||||||
Ok(ok) => ok,
|
Ok(ok) => ok,
|
||||||
Err((errs, config)) => {
|
Err((errs, config)) => {
|
||||||
log::info!("errors loading config: {:?}", errs);
|
log::error!("errors loading config: {:?}", errs);
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -121,15 +125,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
settings = settings.theme(config.app_theme.theme());
|
settings = settings.theme(config.app_theme.theme());
|
||||||
settings = settings.size_limits(Limits::NONE.min_width(360.0).min_height(180.0));
|
settings = settings.size_limits(Limits::NONE.min_width(360.0).min_height(180.0));
|
||||||
|
|
||||||
let argparse::Arguments { urls, url_opt } = argparse::Arguments::from_args().unwrap_or_default();
|
|
||||||
|
|
||||||
let flags = Flags {
|
let flags = Flags {
|
||||||
config_handler,
|
config_handler,
|
||||||
config,
|
config,
|
||||||
config_state_handler,
|
config_state_handler,
|
||||||
config_state,
|
config_state,
|
||||||
url_opt,
|
url_opt: args.url_opt,
|
||||||
urls
|
urls: args.urls,
|
||||||
};
|
};
|
||||||
cosmic::app::run::<App>(settings, flags)?;
|
cosmic::app::run::<App>(settings, flags)?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue