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
114
src/argparse.rs
114
src/argparse.rs
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
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_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) => (),
|
||||
|
|
@ -78,17 +80,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
|
||||
|
||||
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)?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue