From b816c79128e16c9cc086ae4c44d8f111a8f8e302 Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 24 Dec 2020 00:31:49 +0000 Subject: [PATCH] more options formatting --- src/arg/mod.rs | 79 ++++++++++++++++++++++++++++++++++++++------------ src/ext.rs | 27 +++++++++++++++++ 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/src/arg/mod.rs b/src/arg/mod.rs index a46cfba..ee7ebb9 100644 --- a/src/arg/mod.rs +++ b/src/arg/mod.rs @@ -13,42 +13,62 @@ use std::fmt; #[inline] fn options() -> impl Iterator { - struct Opt(&'static [&'static str], Option<&'static str>, &'static str, usize, bool); + struct Opt(&'static [&'static str], Option<&'static str>, &'static str, usize, Option<&'static str>, Option<&'static [&'static str]>); impl Opt { - const fn with_def(self, vl: bool) -> Self + const fn with_def(self, vl: &'static str) -> Self { - Self(self.0, self.1, self.2, self.3, vl) + Self(self.0, self.1, self.2, self.3, Some(vl), self.5) + } + const fn with_slice(self, vl: &'static [&'static str]) -> Self + { + Self(self.0, self.1, self.2, self.3, self.4, Some(vl)) } } + /// Macro for printing the options + /// + /// # Usage + /// Any combination of the following: + /// ``` + /// opt!("--long", "--other"; "Description"); // --long, --other: Description + /// opt!("--long", "--other"; * 2 "Description"); // --long, --other: Description + /// opt!("--long", "--other" => "value name"; "Description"); // --long, --other : Description + /// opt!("--long"; "Description", ""); // --long, --other: Description (default) + /// opt!("--long"; "Description", "Value"); // --long, --other: Description (default: `Value`) + /// opt!("--long"; "Description", ["OTHER", "OTHER 2"], "value"); // --long, --other: Description (see `OTHER`, `OTHER 2`) (default: `value`) + /// ``` macro_rules! opt { - ($($name:literal),* => $num:literal; $desc:literal $(, $def:literal)?) => { + ($($name:literal),* => $num:literal; $desc:literal $(, [$($see:literal),*])? $(, $def:literal)?) => { { - let o = Opt(&[$($name),*], Some($num), $desc, 1, false); + let o = Opt(&[$($name),*], Some($num), $desc, 1, None, None); $(let o = o.with_def($def);)? + $(let o = o.with_slice(&[$($see),*]);)? o } }; - ($($name:literal),* => $num:literal; * $tabs:literal $desc:literal $(, $def:literal)?) => { + ($($name:literal),* => $num:literal; * $tabs:literal $desc:literal $(, [$($see:literal),*])? $(, $def:literal)?) => { { - let o = Opt(&[$($name),*], Some($num), $desc, $tabs, false); + let o = Opt(&[$($name),*], Some($num), $desc, $tabs, None, None); $(let o = o.with_def($def);)? + $(let o = o.with_slice(&[$($see),*]);)? o } }; - ($($name:literal),*; $desc:literal $(, $def:literal)?) => { + ($($name:literal),*; $desc:literal $(, [$($see:literal),*])? $(, $def:literal)?) => { { - let o = Opt(&[$($name),*], None, $desc, 1, false); + let o = Opt(&[$($name),*], None, $desc, 1, None, None); $(let o = o.with_def($def);)? + $(let o = o.with_slice(&[$($see),*]);)? o } }; - ($($name:literal),*; * $tabs:literal $desc:literal $(, $def:literal)?) => { + ($($name:literal),*; * $tabs:literal $desc:literal $(, [$($see:literal),*])? $(, $def:literal)?) => { { - let o = Opt(&[$($name),*], None, $desc, $tabs, false); + let o = Opt(&[$($name),*], None, $desc, $tabs, None, None); $(let o = o.with_def($def);)? + $(let o = o.with_slice(&[$($see),*]);)? o } }; @@ -59,7 +79,8 @@ use std::fmt; { write!(f, " {}", self.0.iter().join(", "))?; if let Some(mx) = self.1 { - write!(f, " {}", mx)?; + use recolored::Colorize; + write!(f, " <{}>", mx.italic())?; } write!(f, ":")?; for ch in std::iter::repeat('\t').take(self.3) @@ -69,18 +90,40 @@ use std::fmt; } write!(f,"{}", self.2)?; - if self.4 { - use recolored::Colorize; - write!(f, " ({})", "default".bold().bright_red())?; + { + use recolored::Colorize; + + match self.5 { + Some(&[]) => (), + Some(strings) => { + write!(f, " (see {})", strings.iter().map(|x| iter!["`".clear(), x.underline(), "`".clear()]).flat_join(", "))?; + } + _ => (), + } + + match self.4 { + Some("") => { + write!(f, " ({})", "default".bold().bright_red())?; + }, + Some(string) => { + write!(f, " ({}: `{}`)", "default".bold().bright_red(), string.bright_blue())?; + }, + None => (), + } } Ok(()) } } iter![ - opt!("--limit", "-l" => ""; "Limit the number of child processes running at once."), - opt!("--auto-limit", "-m"; * 2 "Limit to max number of CPUs + 1", true), - opt!("--unlimit", "-U"; * 3 "No limit to number of processes spawned at once") + opt!("--limit", "-l" => "max children"; "Limit the number of child processes running at once."), + opt!("--auto-limit", "-m"; * 2 "Limit to max number of CPUs + 1", ""), + opt!("--unlimit", "-U"; * 3 "No limit to number of processes spawned at once"), + opt!("--completion", "-c" => "action"; "Set the default action on completion", ["ACTIONS", "COMPLETION"], "ignore"), + opt!("--silent", "-s"; * 3 "Output no messages other than that of child processes"), + opt!("--stdout" => "where"; * 2 "Set default redirect option for childrens' `stdout`", ["ACTIONS"] ,"inherit"), + opt!("--stderr" => "where"; * 2 "Set default redirect option for childrens' `stderr`", ["ACTIONS"], "inherit"), + opt!("--stdin" => "where"; * 2 "Set default redirect option for childrens' `stdin`", ["ACTIONS"], "close") ] } diff --git a/src/ext.rs b/src/ext.rs index db8d1e9..21c7dcd 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -1,6 +1,11 @@ use super::*; use std::fmt; +pub trait FlatJoinStrsExt: Sized +{ + /// Join an iterator of iterators `str` with a seperator + fn flat_join(self, with: &str) -> String; +} pub trait JoinStrsExt: Sized { /// Join an iterator of `str` with a seperator @@ -28,3 +33,25 @@ where I: IntoIterator, output } } + +impl FlatJoinStrsExt for I +where I: IntoIterator, + I2: IntoIterator, + T: fmt::Display +{ + fn flat_join(self, with: &str) -> String + { + let mut output = String::new(); + let mut first=true; + for string in self.into_iter() + { + if !first { + output.push_str(with); + } + let string: String = string.into_iter().map(|x| x.to_string()).collect(); + output.push_str(&string[..]); + first=false; + } + output + } +}