mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/args.rs')
| -rw-r--r-- | src/args.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..fc11992 --- /dev/null +++ b/src/args.rs @@ -0,0 +1,78 @@ +pub trait ArgHandler +{ + type Error; + + fn on_literal(&mut self, name: &str) -> Result<(), Self::Error>; + + fn on_short(&mut self, name: char, value: Option<&str>) -> Result<(), Self::Error>; + + fn on_long(&mut self, name: &str, value: Option<&str>) -> Result<(), Self::Error>; +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Error<E> +{ + Handler(E), + EmptyName, +} + +impl<E> From<E> for Error<E> +{ + fn from(value: E) -> Self + { + Self::Handler(value) + } +} + +pub fn parse<I: Iterator, H: ArgHandler>(args: &mut I, handler: &mut H) -> Result<bool, Error<H::Error>> + where I::Item: AsRef<str> +{ + for arg in args + { + let arg = arg.as_ref(); + if !arg.is_empty() + { + if arg.as_bytes()[0] == b'-' + { + if arg.len() >= 2 && arg.as_bytes()[1] == b'-' + { + if arg == "--" {return Ok(false);} + let (name, value) = match arg.bytes().enumerate().find(|(_, b)| *b == b'=') + { + None => (&arg[2..], None), + Some((i, _)) => (&arg[2..i], Some(&arg[i + 1..])), + }; + if name.is_empty() {return Err(Error::EmptyName);} + handler.on_long(name, value)?; + } + else + { + let (value, end) = match arg.bytes().enumerate().find(|(_, b)| *b == b'=') + { + None => (None, arg.len()), + Some((i, _)) => (Some(&arg[i + 1..]), i), + }; + if end > 2 || (end == 2 && value.is_none()) + { + for c in arg[1..end].chars() + { + handler.on_short(c, value)?; + } + } + else {return Err(Error::EmptyName);} + } + } + else + { + handler.on_literal(arg)?; + } + } + } + Ok(true) +} + +pub fn parse_args<H: ArgHandler>(handler: &mut H) -> Result<(), Error<H::Error>> +{ + parse(&mut std::env::args(), handler)?; + Ok(()) +} |