From deddddcdce7453ff5b3cfb2f16a7ac24372f31c9 Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 25 Feb 2021 22:16:38 +0000 Subject: [PATCH] mode selection process outlined in 'arg::parsing::into_mode' --- src/arg/parsing.rs | 55 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/arg/parsing.rs b/src/arg/parsing.rs index bfdb73d..247d30a 100644 --- a/src/arg/parsing.rs +++ b/src/arg/parsing.rs @@ -32,10 +32,43 @@ pub enum Argument Input(String), } +/// Kinds of modes of operation for the program. +/// +/// These map to `super::Mode`. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] +#[non_exhaustive] +enum ModeKind +{ + Normal, + + Help +} + +impl Default for ModeKind +{ + #[inline] + fn default() -> Self + { + Self::Normal + } +} + + impl Argument { + /// What mode does this argument change to, if any? + fn mode_change_kind(&self) -> Option + { + Some(match self + { + Self::ModeChangeHelp => ModeKind::Help, + _ => return None, + }) + } /// Convert into a mode change if this is a mode change // We consume the whole output here in case the mode change needs to traverse it for information. As of now, we have only one non-`Normal` mode: `Help`, which doesn't require any extra information. + + #[deprecated(note = "mode selection happens in `into_mode` and early return through `Continue::Abort` will be removed or reworked to not require this function.")] pub fn try_into_mode(self, _rest: Output) -> Result { match self { @@ -233,6 +266,8 @@ pub enum Continue /// /// Returning this when the contained value is `Some` immediately terminates parsing and precedes to mode-switch. However, if it is `None`, parsing of chained short args is allowed to continue, although `Abort(None)` will be returned at the end regardless of subsequent `Continue` results from that change (unless one is an `Abort(Some(_))`, which immediately returns itself.) // Box `Argument` to reduce the size of `Continue`, as it is returned from functions often and when its value is set to `Some` it will always be the last `Argument` processed anyway and the only one to be boxed here at all. + + //TODO: Deprecate the early return of an `Argument` here. Either change it to `Mode`, or have no early return. Mode change happens at the bottom in `into_mode` now. Abort(Option>), } @@ -416,9 +451,21 @@ mod modes { /// Consume this parsed list of arguments into a `Mode` and return it pub fn into_mode(args: Output) -> eyre::Result { - //TODO: Find out what mode `args` is in. - - //TODO: pass `args` to the respective mode generation function in mode `modes`, and wrap that mode around its return value. + let mut mode_kind = ModeKind::default(); //Normal. + + for arg in args.iter() { + //find any mode change Argument (with `Argument::mode_change_kind()`) in `args`, changing `mode_kind` in turn. There should be at most 1. + if let Some(mode) = arg.mode_change_kind() + { + mode_kind = mode; + break; + } + } + //pass `args` to the respective mode generation function in mode `modes`, and wrap that mode around its return value. + match mode_kind + { + ModeKind::Normal => modes::normal(args).map(Mode::Normal), + ModeKind::Help => Ok(Mode::Help), + } - todo!() }