diff options
Diffstat (limited to 'mingling')
| -rw-r--r-- | mingling/src/parser/picker.rs | 473 |
1 files changed, 366 insertions, 107 deletions
diff --git a/mingling/src/parser/picker.rs b/mingling/src/parser/picker.rs index d071204..4641a49 100644 --- a/mingling/src/parser/picker.rs +++ b/mingling/src/parser/picker.rs @@ -1,5 +1,3 @@ -use std::marker::PhantomData; - use crate::parser::Argument; use mingling_core::{EnumTag, Flag}; @@ -13,27 +11,22 @@ pub mod bools; /// /// The `Picker` struct holds parsed arguments and provides a fluent interface /// to extract values associated with specific flags. -pub struct Picker<G> { +pub struct Picker { /// The parsed command-line arguments. pub args: Argument, - - _phantom: PhantomData<G>, } -impl<R> Picker<R> { +impl Picker { /// Creates a new `Picker` from a value that can be converted into `Argument`. - pub fn new(args: impl Into<Argument>) -> Picker<R> { - Picker { - args: args.into(), - _phantom: PhantomData, - } + pub fn new(args: impl Into<Argument>) -> Picker { + Picker { args: args.into() } } - /// Extracts a value for the given flag and returns a `Pick1` builder. + /// Extracts a value for the given flag and returns a `Pick1` builder (no route). /// /// The extracted type `TNext` must implement `Pickable` and `Default`. /// If the flag is not present, the default value for `TNext` is used. - pub fn pick<TNext>(mut self, val: impl Into<Flag>) -> Pick1<TNext, R> + pub fn pick<TNext>(mut self, val: impl Into<Flag>) -> Pick1<TNext> where TNext: Pickable<Output = TNext> + Default, { @@ -41,16 +34,15 @@ impl<R> Picker<R> { Pick1 { args: self.args, val_1: v, - route: None, } } /// Extracts a value for the given flag, returning the provided default value if not present, - /// and returns a `Pick1` builder. + /// and returns a `Pick1` builder (no route). /// /// The extracted type `TNext` must implement `Pickable`. /// If the flag is not present, the provided `or` value is used. - pub fn pick_or<TNext>(mut self, val: impl Into<Flag>, or: impl Into<TNext>) -> Pick1<TNext, R> + pub fn pick_or<TNext>(mut self, val: impl Into<Flag>, or: impl Into<TNext>) -> Pick1<TNext> where TNext: Pickable<Output = TNext>, { @@ -58,31 +50,34 @@ impl<R> Picker<R> { Pick1 { args: self.args, val_1: v, - route: None, } } /// Extracts a value for the given flag, storing the provided route if the flag is not present, - /// and returns a `Pick1` builder. + /// and returns a `PickWithRoute1` builder (with route). /// /// The extracted type `TNext` must implement `Pickable` and `Default`. /// If the flag is not present, the default value for `TNext` is used and the provided `route` /// is stored in the returned builder for later error handling. - pub fn pick_or_route<TNext>(mut self, val: impl Into<Flag>, route: R) -> Pick1<TNext, R> + pub fn pick_or_route<TNext, R>( + mut self, + val: impl Into<Flag>, + route: R, + ) -> PickWithRoute1<TNext, R> where TNext: Pickable<Output = TNext> + Default, { let v = match TNext::pick(&mut self.args, val.into()) { Some(value) => value, None => { - return Pick1 { + return PickWithRoute1 { args: self.args, val_1: TNext::default(), route: Some(route), }; } }; - Pick1 { + PickWithRoute1 { args: self.args, val_1: v, route: None, @@ -90,11 +85,11 @@ impl<R> Picker<R> { } /// Extracts a value for the given flag, returning `None` if the flag is not present, - /// and returns an `Option<Pick1<TNext>>` builder. + /// and returns an `Option<Pick1<TNext>>` builder (no route). /// /// The extracted type `TNext` must implement `Pickable`. /// If the flag is not present, `None` is returned. - pub fn require<TNext>(mut self, val: impl Into<Flag>) -> Option<Pick1<TNext, R>> + pub fn require<TNext>(mut self, val: impl Into<Flag>) -> Option<Pick1<TNext>> where TNext: Pickable<Output = TNext>, { @@ -103,7 +98,6 @@ impl<R> Picker<R> { Some(s) => Some(Pick1 { args: self.args, val_1: s, - route: None, }), None => None, } @@ -120,7 +114,7 @@ impl<R> Picker<R> { } } -impl<T: Into<Argument>, G> From<T> for Picker<G> { +impl<T: Into<Argument>> From<T> for Picker { fn from(value: T) -> Self { Picker::new(value) } @@ -140,9 +134,283 @@ pub trait Pickable { fn pick(args: &mut Argument, flag: Flag) -> Option<Self::Output>; } +// Non-routed Pick structs (no R parameter, no route field) + /// Internal macro: generates the struct definition and common methods -/// (after, after_or_route, operate_args) for Pick2 through Pick12. +/// (after, after_or_route, operate_args) for non-routed Pick structs. macro_rules! define_pick_struct { + ($n:ident $final:ident $final_val:ident $route_self:ident $($T:ident $val:ident),+ $(,)?) => { + #[doc(hidden)] + pub struct $n<$($T,)+> + where + $($T: Pickable,)+ + { + #[allow(dead_code)] + args: Argument, + $(pub $val: $T,)+ + } + + impl<$($T,)+> $n<$($T,)+> + where + $($T: Pickable,)+ + { + /// Applies a transformation to the last extracted value. + /// + /// Takes a closure that receives the last extracted value and returns a new value of the same type. + /// The transformed value replaces the original value in the builder. + /// This method can be used to modify or validate the extracted value before final unpacking. + pub fn after<F>(mut self, mut edit: F) -> Self + where + F: FnMut($final) -> $final, + { + self.$final_val = edit(self.$final_val); + self + } + + /// Applies a transformation to the last extracted value, storing a route if the transformation fails. + /// + /// Takes a closure that receives a reference to the last extracted value and returns a `Result`. + /// If the closure returns `Ok(new_value)`, the new value replaces the original value in the builder. + /// If the closure returns `Err(route)`, the provided `route` is stored in the builder for later error handling. + /// If a route was already stored from a previous `pick_or_route` call, the existing route is preserved. + pub fn after_or_route<F, R>(mut self, mut edit: F) -> $route_self<$($T,)+ R> + where + F: FnMut(&$final) -> Result<$final, R>, + { + match edit(&self.$final_val) { + Ok(new_value) => { + self.$final_val = new_value; + $route_self { + args: self.args, + $($val: self.$val,)+ + route: None, + } + } + Err(err_route) => { + $route_self { + args: self.args, + $($val: self.$val,)+ + route: Some(err_route), + } + } + } + } + + /// Applies an operation to the parsed arguments and returns the modified builder. + /// + /// Takes a closure that receives the current `Argument` and returns a new `Argument`. + /// The returned `Argument` replaces the original arguments in the builder. + /// This method can be used to modify or transform the parsed arguments before extracting values. + pub fn operate_args<F: FnOnce(Argument) -> Argument>(mut self, operation: F) -> Self { + self.args = operation(self.args); + self + } + } + }; +} + +// Pick1 special case (single value) + +define_pick_struct! { Pick1 T1 val_1 PickWithRoute1 T1 val_1 } + +impl<T1> From<Pick1<T1>> for (T1,) +where + T1: Pickable, +{ + fn from(pick: Pick1<T1>) -> Self { + (pick.val_1,) + } +} + +impl<T1> Pick1<T1> +where + T1: Pickable, +{ + /// Unpacks the builder into the extracted value. + /// + /// Always returns the value directly since there is no route. + pub fn unpack(self) -> T1 { + self.val_1 + } +} + +// Pick2 .. Pick12 + +macro_rules! impl_pick_from_tuple { + ($n:ident $($T:ident $val:ident),+) => { + impl<$($T,)+> From<$n<$($T,)+>> for ($($T,)+) + where + $($T: Pickable,)+ + { + fn from(pick: $n<$($T,)+>) -> Self { + ($(pick.$val,)+) + } + } + }; +} + +macro_rules! impl_pick_unpack_tuple { + ($n:ident $($T:ident $val:ident),+) => { + impl<$($T,)+> $n<$($T,)+> + where + $($T: Pickable,)+ + { + /// Unpacks the builder into a tuple of extracted values. + /// + /// Always returns the tuple directly since there is no route. + pub fn unpack(self) -> ($($T,)+) { + ($(self.$val,)+) + } + } + }; +} + +define_pick_struct! { Pick2 T2 val_2 PickWithRoute2 T1 val_1, T2 val_2 } +impl_pick_from_tuple! { Pick2 T1 val_1, T2 val_2 } +impl_pick_unpack_tuple! { Pick2 T1 val_1, T2 val_2 } + +define_pick_struct! { Pick3 T3 val_3 PickWithRoute3 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_from_tuple! { Pick3 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_unpack_tuple! { Pick3 T1 val_1, T2 val_2, T3 val_3 } + +define_pick_struct! { Pick4 T4 val_4 PickWithRoute4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_from_tuple! { Pick4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_unpack_tuple! { Pick4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } + +define_pick_struct! { Pick5 T5 val_5 PickWithRoute5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_from_tuple! { Pick5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_unpack_tuple! { Pick5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } + +define_pick_struct! { Pick6 T6 val_6 PickWithRoute6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_from_tuple! { Pick6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_unpack_tuple! { Pick6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } + +define_pick_struct! { Pick7 T7 val_7 PickWithRoute7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_from_tuple! { Pick7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_unpack_tuple! { Pick7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } + +define_pick_struct! { Pick8 T8 val_8 PickWithRoute8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_from_tuple! { Pick8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_unpack_tuple! { Pick8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } + +define_pick_struct! { Pick9 T9 val_9 PickWithRoute9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_from_tuple! { Pick9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_unpack_tuple! { Pick9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } + +define_pick_struct! { Pick10 T10 val_10 PickWithRoute10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_from_tuple! { Pick10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_unpack_tuple! { Pick10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } + +define_pick_struct! { Pick11 T11 val_11 PickWithRoute11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +impl_pick_from_tuple! { Pick11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +impl_pick_unpack_tuple! { Pick11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } + +define_pick_struct! { Pick12 T12 val_12 PickWithRoute12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } +impl_pick_from_tuple! { Pick12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } +impl_pick_unpack_tuple! { Pick12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } + +// Non-routed Pick chaining methods (pick, pick_or, pick_or_route, require) + +#[doc(hidden)] +macro_rules! impl_pick_next { + ($n:ident $next:ident $next_val:ident $route_next:ident $($T:ident $val:ident),+) => { + impl<$($T,)+> $n<$($T,)+> + where + $($T: Pickable,)+ + { + /// Extracts a value for the given flag and returns a `PickN` builder (no route). + pub fn pick<TNext>(mut self, val: impl Into<mingling_core::Flag>) -> $next<$($T,)+ TNext> + where + TNext: Pickable<Output = TNext> + Default, + { + let v = TNext::pick(&mut self.args, val.into()).unwrap_or_default(); + $next { + args: self.args, + $($val: self.$val,)+ + $next_val: v, + } + } + + /// Extracts a value for the given flag, returning the provided default value if not present, + /// and returns a `PickN` builder (no route). + pub fn pick_or<TNext>(mut self, val: impl Into<mingling_core::Flag>, or: impl Into<TNext>) -> $next<$($T,)+ TNext> + where + TNext: Pickable<Output = TNext>, + { + let v = TNext::pick(&mut self.args, val.into()).unwrap_or(or.into()); + $next { + args: self.args, + $($val: self.$val,)+ + $next_val: v, + } + } + + /// Extracts a value for the given flag, storing the provided route if the flag is not present, + /// and returns a `PickWithRouteN` builder (with route). + pub fn pick_or_route<TNext, R>( + mut self, + val: impl Into<mingling_core::Flag>, + route: R, + ) -> $route_next<$($T,)+ TNext, R> + where + TNext: Pickable<Output = TNext> + Default, + { + let v = match TNext::pick(&mut self.args, val.into()) { + Some(value) => value, + None => { + return $route_next { + args: self.args, + $($val: self.$val,)+ + $next_val: TNext::default(), + route: Some(route), + }; + } + }; + $route_next { + args: self.args, + $($val: self.$val,)+ + $next_val: v, + route: None, + } + } + + /// Extracts a value for the given flag, returning `None` if the flag is not present, + /// and returns an `Option<PickN<TNext>>` builder (no route). + pub fn require<TNext>(mut self, val: impl Into<mingling_core::Flag>) -> Option<$next<$($T,)+ TNext>> + where + TNext: Pickable<Output = TNext>, + { + let v = TNext::pick(&mut self.args, val.into()); + match v { + Some(s) => Some($next { + args: self.args, + $($val: self.$val,)+ + $next_val: s, + }), + None => None, + } + } + } + }; +} + +impl_pick_next! { Pick1 Pick2 val_2 PickWithRoute2 T1 val_1 } +impl_pick_next! { Pick2 Pick3 val_3 PickWithRoute3 T1 val_1, T2 val_2 } +impl_pick_next! { Pick3 Pick4 val_4 PickWithRoute4 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_next! { Pick4 Pick5 val_5 PickWithRoute5 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_next! { Pick5 Pick6 val_6 PickWithRoute6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_next! { Pick6 Pick7 val_7 PickWithRoute7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_next! { Pick7 Pick8 val_8 PickWithRoute8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_next! { Pick8 Pick9 val_9 PickWithRoute9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_next! { Pick9 Pick10 val_10 PickWithRoute10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_next! { Pick10 Pick11 val_11 PickWithRoute11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_next! { Pick11 Pick12 val_12 PickWithRoute12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } + +// Routed PickWithRoute structs (with R parameter, route field) + +/// Internal macro: generates the routed struct definition and common methods +/// (after, after_or_route, operate_args) for PickWithRoute structs. +macro_rules! define_pick_with_route_struct { ($n:ident $final:ident $final_val:ident $($T:ident $val:ident),+) => { #[doc(hidden)] pub struct $n<$($T,)+ R> @@ -211,8 +479,8 @@ macro_rules! define_pick_struct { }; } -/// Internal macro: generates `From` impl for PickN into a tuple. -macro_rules! impl_pick_from_tuple { +/// Internal macro: generates `From` impl for routed PickWithRouteN into a tuple. +macro_rules! impl_pick_with_route_from_tuple { ($n:ident $($T:ident $val:ident),+) => { impl<$($T,)+ R> From<$n<$($T,)+ R>> for ($($T,)+) where @@ -225,9 +493,8 @@ macro_rules! impl_pick_from_tuple { }; } -/// Internal macro: generates `unpack` and `unpack_directly` for PickN (N >= 2) -/// that return a tuple. -macro_rules! impl_pick_unpack_tuple { +/// Internal macro: generates `unpack` and `unpack_directly` for routed PickWithRouteN (N >= 2). +macro_rules! impl_pick_with_route_unpack_tuple { ($n:ident $($T:ident $val:ident),+) => { impl<$($T,)+ R> $n<$($T,)+ R> where @@ -235,8 +502,8 @@ macro_rules! impl_pick_unpack_tuple { { /// Unpacks the builder into a tuple of extracted values. /// - /// Returns `Ok((T1, T2, ...))` if all required flags were present. - /// Returns `Err(R)` if a required flag was missing and a route was provided via `pick_or_route`. + /// Returns `Ok((T1, T2, ...))` if no route was stored. + /// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`. pub fn unpack(self) -> Result<($($T,)+), R> { match self.route { Some(route) => Err(route), @@ -246,9 +513,7 @@ macro_rules! impl_pick_unpack_tuple { /// Unpacks the builder into a tuple of extracted values. /// - /// Returns the tuple of extracted values regardless of whether any required flags were missing. - /// If a required flag was missing and a route was provided via `pick_or_route`, the default value - /// for that type is included in the tuple. + /// Returns the tuple of extracted values regardless of route state. pub fn unpack_directly(self) -> ($($T,)+) { ($(self.$val,)+) } @@ -256,25 +521,27 @@ macro_rules! impl_pick_unpack_tuple { }; } -define_pick_struct! { Pick1 T1 val_1 T1 val_1 } +// PickWithRoute1 special case (single value) + +define_pick_with_route_struct! { PickWithRoute1 T1 val_1 T1 val_1 } -impl<T1, R> From<Pick1<T1, R>> for (T1,) +impl<T1, R> From<PickWithRoute1<T1, R>> for (T1,) where T1: Pickable, { - fn from(pick: Pick1<T1, R>) -> Self { + fn from(pick: PickWithRoute1<T1, R>) -> Self { (pick.val_1,) } } -impl<T1, R> Pick1<T1, R> +impl<T1, R> PickWithRoute1<T1, R> where T1: Pickable, { - /// Unpacks the builder into a tuple of extracted values. + /// Unpacks the builder into the extracted value. /// - /// Returns `Ok((T1, T2, ...))` if all required flags were present. - /// Returns `Err(R)` if a required flag was missing and a route was provided via `pick_or_route`. + /// Returns `Ok(T1)` if no route was stored. + /// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`. pub fn unpack(self) -> Result<T1, R> { match self.route { Some(route) => Err(route), @@ -282,68 +549,70 @@ where } } - /// Unpacks the builder into a tuple of extracted values. + /// Unpacks the builder into the extracted value. /// - /// Returns the tuple of extracted values regardless of whether any required flags were missing. - /// If a required flag was missing and a route was provided via `pick_or_route`, the default value - /// for that type is included in the tuple. + /// Returns the extracted value regardless of route state. pub fn unpack_directly(self) -> T1 { self.val_1 } } -define_pick_struct! { Pick2 T2 val_2 T1 val_1, T2 val_2 } -impl_pick_from_tuple! { Pick2 T1 val_1, T2 val_2 } -impl_pick_unpack_tuple! { Pick2 T1 val_1, T2 val_2 } +// PickWithRoute2 .. PickWithRoute12 -define_pick_struct! { Pick3 T3 val_3 T1 val_1, T2 val_2, T3 val_3 } -impl_pick_from_tuple! { Pick3 T1 val_1, T2 val_2, T3 val_3 } -impl_pick_unpack_tuple! { Pick3 T1 val_1, T2 val_2, T3 val_3 } +define_pick_with_route_struct! { PickWithRoute2 T2 val_2 T1 val_1, T2 val_2 } +impl_pick_with_route_from_tuple! { PickWithRoute2 T1 val_1, T2 val_2 } +impl_pick_with_route_unpack_tuple! { PickWithRoute2 T1 val_1, T2 val_2 } -define_pick_struct! { Pick4 T4 val_4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } -impl_pick_from_tuple! { Pick4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } -impl_pick_unpack_tuple! { Pick4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +define_pick_with_route_struct! { PickWithRoute3 T3 val_3 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_with_route_from_tuple! { PickWithRoute3 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_with_route_unpack_tuple! { PickWithRoute3 T1 val_1, T2 val_2, T3 val_3 } -define_pick_struct! { Pick5 T5 val_5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } -impl_pick_from_tuple! { Pick5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } -impl_pick_unpack_tuple! { Pick5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +define_pick_with_route_struct! { PickWithRoute4 T4 val_4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_with_route_from_tuple! { PickWithRoute4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_with_route_unpack_tuple! { PickWithRoute4 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } -define_pick_struct! { Pick6 T6 val_6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } -impl_pick_from_tuple! { Pick6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } -impl_pick_unpack_tuple! { Pick6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +define_pick_with_route_struct! { PickWithRoute5 T5 val_5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_with_route_from_tuple! { PickWithRoute5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_with_route_unpack_tuple! { PickWithRoute5 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } -define_pick_struct! { Pick7 T7 val_7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } -impl_pick_from_tuple! { Pick7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } -impl_pick_unpack_tuple! { Pick7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +define_pick_with_route_struct! { PickWithRoute6 T6 val_6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_with_route_from_tuple! { PickWithRoute6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_with_route_unpack_tuple! { PickWithRoute6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } -define_pick_struct! { Pick8 T8 val_8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } -impl_pick_from_tuple! { Pick8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } -impl_pick_unpack_tuple! { Pick8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +define_pick_with_route_struct! { PickWithRoute7 T7 val_7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_with_route_from_tuple! { PickWithRoute7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_with_route_unpack_tuple! { PickWithRoute7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } -define_pick_struct! { Pick9 T9 val_9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } -impl_pick_from_tuple! { Pick9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } -impl_pick_unpack_tuple! { Pick9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +define_pick_with_route_struct! { PickWithRoute8 T8 val_8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_with_route_from_tuple! { PickWithRoute8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_with_route_unpack_tuple! { PickWithRoute8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } -define_pick_struct! { Pick10 T10 val_10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } -impl_pick_from_tuple! { Pick10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } -impl_pick_unpack_tuple! { Pick10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +define_pick_with_route_struct! { PickWithRoute9 T9 val_9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_with_route_from_tuple! { PickWithRoute9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_with_route_unpack_tuple! { PickWithRoute9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } -define_pick_struct! { Pick11 T11 val_11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } -impl_pick_from_tuple! { Pick11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } -impl_pick_unpack_tuple! { Pick11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +define_pick_with_route_struct! { PickWithRoute10 T10 val_10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_with_route_from_tuple! { PickWithRoute10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_with_route_unpack_tuple! { PickWithRoute10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } -define_pick_struct! { Pick12 T12 val_12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } -impl_pick_from_tuple! { Pick12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } -impl_pick_unpack_tuple! { Pick12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } +define_pick_with_route_struct! { PickWithRoute11 T11 val_11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +impl_pick_with_route_from_tuple! { PickWithRoute11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +impl_pick_with_route_unpack_tuple! { PickWithRoute11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } + +define_pick_with_route_struct! { PickWithRoute12 T12 val_12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } +impl_pick_with_route_from_tuple! { PickWithRoute12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } +impl_pick_with_route_unpack_tuple! { PickWithRoute12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11, T12 val_12 } + +// Routed PickWithRoute chaining methods (pick, pick_or, pick_or_route, require) #[doc(hidden)] -macro_rules! impl_pick_structs { +macro_rules! impl_pick_with_route_next { ($n:ident $next:ident $next_val:ident $($T:ident $val:ident),+) => { impl<$($T,)+ R> $n<$($T,)+ R> where $($T: Pickable,)+ { - /// Extracts a value for the given flag and returns a `PickN` builder. + /// Extracts a value for the given flag and returns a `PickWithRouteN` builder. pub fn pick<TNext>(mut self, val: impl Into<mingling_core::Flag>) -> $next<$($T,)+ TNext, R> where TNext: Pickable<Output = TNext> + Default, @@ -358,10 +627,7 @@ macro_rules! impl_pick_structs { } /// Extracts a value for the given flag, returning the provided default value if not present, - /// and returns a `PickN` builder. - /// - /// The extracted type `TNext` must implement `Pickable`. - /// If the flag is not present, the provided `or` value is used. + /// and returns a `PickWithRouteN` builder. pub fn pick_or<TNext>(mut self, val: impl Into<mingling_core::Flag>, or: impl Into<TNext>) -> $next<$($T,)+ TNext, R> where TNext: Pickable<Output = TNext>, @@ -376,13 +642,9 @@ macro_rules! impl_pick_structs { } /// Extracts a value for the given flag, storing the provided route if the flag is not present, - /// and returns a `PickN` builder. - /// - /// The extracted type `TNext` must implement `Pickable` and `Default`. - /// If the flag is not present, the default value for `TNext` is used and the provided `route` - /// is stored in the returned builder for later error handling. + /// and returns a `PickWithRouteN` builder. /// - /// If a route was already stored from a previous `pick_or_route` call (i.e., `self.route` is `Some`), + /// If a route was already stored from a previous `pick_or_route` or `after_or_route` call, /// the existing route is preserved and the new `route` parameter is ignored. pub fn pick_or_route<TNext>(mut self, val: impl Into<mingling_core::Flag>, route: R) -> $next<$($T,)+ TNext, R> where @@ -412,10 +674,7 @@ macro_rules! impl_pick_structs { } /// Extracts a value for the given flag, returning `None` if the flag is not present, - /// and returns an `Option<PickN<TNext>>` builder. - /// - /// The extracted type `TNext` must implement `Pickable`. - /// If the flag is not present, `None` is returned. + /// and returns an `Option<PickWithRouteN>` builder. pub fn require<TNext>(mut self, val: impl Into<mingling_core::Flag>) -> Option<$next<$($T,)+ TNext, R>> where TNext: Pickable<Output = TNext>, @@ -435,17 +694,17 @@ macro_rules! impl_pick_structs { }; } -impl_pick_structs! { Pick1 Pick2 val_2 T1 val_1 } -impl_pick_structs! { Pick2 Pick3 val_3 T1 val_1, T2 val_2 } -impl_pick_structs! { Pick3 Pick4 val_4 T1 val_1, T2 val_2, T3 val_3 } -impl_pick_structs! { Pick4 Pick5 val_5 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } -impl_pick_structs! { Pick5 Pick6 val_6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } -impl_pick_structs! { Pick6 Pick7 val_7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } -impl_pick_structs! { Pick7 Pick8 val_8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } -impl_pick_structs! { Pick8 Pick9 val_9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } -impl_pick_structs! { Pick9 Pick10 val_10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } -impl_pick_structs! { Pick10 Pick11 val_11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } -impl_pick_structs! { Pick11 Pick12 val_12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } +impl_pick_with_route_next! { PickWithRoute1 PickWithRoute2 val_2 T1 val_1 } +impl_pick_with_route_next! { PickWithRoute2 PickWithRoute3 val_3 T1 val_1, T2 val_2 } +impl_pick_with_route_next! { PickWithRoute3 PickWithRoute4 val_4 T1 val_1, T2 val_2, T3 val_3 } +impl_pick_with_route_next! { PickWithRoute4 PickWithRoute5 val_5 T1 val_1, T2 val_2, T3 val_3, T4 val_4 } +impl_pick_with_route_next! { PickWithRoute5 PickWithRoute6 val_6 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5 } +impl_pick_with_route_next! { PickWithRoute6 PickWithRoute7 val_7 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6 } +impl_pick_with_route_next! { PickWithRoute7 PickWithRoute8 val_8 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7 } +impl_pick_with_route_next! { PickWithRoute8 PickWithRoute9 val_9 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8 } +impl_pick_with_route_next! { PickWithRoute9 PickWithRoute10 val_10 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9 } +impl_pick_with_route_next! { PickWithRoute10 PickWithRoute11 val_11 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10 } +impl_pick_with_route_next! { PickWithRoute11 PickWithRoute12 val_12 T1 val_1, T2 val_2, T3 val_3, T4 val_4, T5 val_5, T6 val_6, T7 val_7, T8 val_8, T9 val_9, T10 val_10, T11 val_11 } pub trait PickableEnum: EnumTag + Default {} |
