feat: add help and version flags to argument parser

This commit is contained in:
LinuxBoy-96 2025-03-26 11:42:39 -04:00 committed by GitHub
parent 69475d098c
commit 01be9152a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 202 additions and 46 deletions

100
Cargo.lock generated
View file

@ -184,6 +184,12 @@ dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "apply"
version = "0.3.0"
@ -844,6 +850,12 @@ dependencies = [
"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]]
name = "clipboard-win"
version = "5.4.0"
@ -1070,6 +1082,7 @@ dependencies = [
name = "cosmic-player"
version = "0.1.0"
dependencies = [
"clap_lex",
"dirs",
"env_logger",
"fork",
@ -1084,13 +1097,13 @@ dependencies = [
"libcosmic",
"log",
"mpris-server",
"pico-args",
"rust-embed",
"serde",
"smol_str",
"tempfile",
"tokio",
"url",
"vergen",
]
[[package]]
@ -1292,6 +1305,15 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "deranged"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
dependencies = [
"powerfmt",
]
[[package]]
name = "derivative"
version = "2.2.0"
@ -3680,6 +3702,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.46"
@ -3752,6 +3780,15 @@ dependencies = [
"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]]
name = "objc"
version = "0.2.7"
@ -4139,6 +4176,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
@ -4561,6 +4604,12 @@ dependencies = [
"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]]
name = "rustybuzz"
version = "0.12.1"
@ -4796,9 +4845,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.2"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "smithay-client-toolkit"
@ -5138,6 +5187,39 @@ dependencies = [
"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]]
name = "tiny-keccak"
version = "2.0.2"
@ -5575,6 +5657,18 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "version-compare"
version = "0.2.0"

View file

@ -3,6 +3,9 @@ name = "cosmic-player"
version = "0.1.0"
edition = "2021"
[build-dependencies]
vergen = { version = "8", features = ["git", "gitcl"] }
[dependencies]
dirs = "5"
gstreamer-tag = "0.23"
@ -12,11 +15,15 @@ serde = { version = "1", features = ["serde_derive"] }
tempfile = "3"
tokio = "1"
url = "2"
pico-args = "0.5"
# CLI arguments
clap_lex = "0.7"
# Internationalization
icu_collator = "1.5"
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"
rust-embed = "8"
# Logging
@ -61,4 +68,3 @@ debug = true
# libcosmic = { path = "../libcosmic" }
# cosmic-config = { path = "../libcosmic/cosmic-config" }
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }

6
build.rs Normal file
View file

@ -0,0 +1,6 @@
use vergen::EmitBuilder;
fn main() {
EmitBuilder::builder().git_sha(true).emit().unwrap();
}

View file

@ -3,9 +3,57 @@
use std::{fs, io};
use clap_lex::RawArgs;
use log::warn;
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)]
pub struct Arguments {
/// Files or directory URLs to play
@ -14,39 +62,6 @@ pub struct Arguments {
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)]
// pub enum Source {
// 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);
}

View file

@ -52,6 +52,8 @@ const GST_PLAY_FLAG_VIDEO: i32 = 1 << 0;
const GST_PLAY_FLAG_AUDIO: i32 = 1 << 1;
const GST_PLAY_FLAG_TEXT: i32 = 1 << 2;
use std::error::Error;
fn language_name(code: &str) -> Option<String> {
let code_c = CString::new(code).ok()?;
let name_c = unsafe {
@ -68,7 +70,7 @@ fn language_name(code: &str) -> Option<String> {
/// Runs application with these settings
#[rustfmt::skip]
fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() -> Result<(), Box<dyn Error>> {
#[cfg(all(unix, not(target_os = "redox")))]
match fork::daemon(true, true) {
Ok(fork::Fork::Child) => (),
@ -83,12 +85,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
localize::localize();
let args = argparse::parse();
let (config_handler, config) = match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) {
Ok(config_handler) => {
let config = match Config::get_entry(&config_handler) {
Ok(ok) => ok,
Err((errs, config)) => {
log::info!("errors loading config: {:?}", errs);
log::error!("errors loading config: {:?}", errs);
config
}
};
@ -121,15 +125,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
settings = settings.theme(config.app_theme.theme());
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 {
config_handler,
config,
config_state_handler,
config_state,
url_opt,
urls
url_opt: args.url_opt,
urls: args.urls,
};
cosmic::app::run::<App>(settings, flags)?;