mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/exe/args.rs')
| -rw-r--r-- | src/exe/args.rs | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/src/exe/args.rs b/src/exe/args.rs index 9ea30aa..afd9e72 100644 --- a/src/exe/args.rs +++ b/src/exe/args.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::collections::HashMap; +use std::fmt; use std::slice::from_ref; pub trait ArgHandler @@ -20,7 +21,19 @@ pub enum Error<E> EmptyName{pos: usize}, } -pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H) -> Result<bool, Error<H::Error>> +impl<E: fmt::Display> fmt::Display for Error<E> +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match self + { + Error::Handler{pos, val} => write!(f, "{val} (at #{pos})"), + Error::EmptyName{pos} => write!(f, "Malformed argument (at #{pos})"), + } + } +} + +pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H, arg_off: usize) -> Result<bool, Error<H::Error>> where I::Item: AsRef<str> { for (pos, arg) in args.enumerate() @@ -38,10 +51,10 @@ pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H) -> Resul None => (&arg[2..], None), Some((i, _)) => (&arg[2..i], Some(&arg[i + 1..])), }; - if name.is_empty() {return Err(Error::EmptyName{pos});} + if name.is_empty() {return Err(Error::EmptyName{pos: arg_off + pos});} if let Err(val) = handler.on_long(name, value) { - return Err(Error::Handler{pos, val}); + return Err(Error::Handler{pos: arg_off + pos, val}); } } else @@ -57,18 +70,18 @@ pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H) -> Resul { if let Err(val) = handler.on_short(c, value) { - return Err(Error::Handler{pos, val}); + return Err(Error::Handler{pos: arg_off + pos, val}); } } } - else {return Err(Error::EmptyName{pos});} + else {return Err(Error::EmptyName{pos: arg_off + pos});} } } else { if let Err(val) = handler.on_literal(arg) { - return Err(Error::Handler{pos, val}); + return Err(Error::Handler{pos: arg_off + pos, val}); } } } @@ -78,7 +91,7 @@ pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H) -> Resul pub fn parse_args<H: ArgHandler>(handler: &mut H) -> Result<(), Error<H::Error>> { - parse(&mut std::env::args(), handler)?; + parse(&mut std::env::args(), handler, 0)?; Ok(()) } @@ -167,6 +180,20 @@ impl ArgOption } } +impl fmt::Display for ArgOption +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match (self.get_short(), self.get_long()) + { + (None, None) => unreachable!("unnamed ArgOption"), + (None, Some(long)) => write!(f, "\"--{long}\""), + (Some(short), None) => write!(f, "\"-{short}\""), + (Some(short), Some(long)) => write!(f, "\"--{long}\" / \"-{short}\""), + } + } +} + #[derive(Clone, Debug, Eq, PartialEq)] pub enum OptionValue { @@ -434,3 +461,22 @@ pub enum OptionError ValueRequired(ArgOption), TooMany(ArgOption), } + +impl fmt::Display for OptionError +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match self + { + OptionError::NoSuchShort(short) => write!(f, "Invalid argument \"-{short}\""), + OptionError::NoSuchLong(long) => write!(f, "Invalid argument \"--{long}\""), + OptionError::ValueForbidden(opt) => write!(f, "Argument {opt} has no value"), + OptionError::ValueRequired(opt) => write!(f, "Argument {opt} requires a value"), + OptionError::TooMany(opt) => + { + if let Some(max) = opt.count.get_max_count() {write!(f, "Too many {opt} (max {max})")} + else {write!(f, "Duplicate argument {opt}")} + }, + } + } +} |