From 75f420f8d50910888822c412724ff80fbce32ac5 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 15 Jul 2026 20:30:40 +0800 Subject: feat(picker): remove route phantom from IntoPicker trait Add `with_route` methods to `IntoPicker` and `PickerPattern` for setting the route type explicitly when needed, instead of carrying it as a generic parameter on the trait itself. --- mingling_picker/src/picker.rs | 37 ++++++++++++++++++++++++---------- mingling_picker/src/picker/patterns.rs | 26 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/mingling_picker/src/picker.rs b/mingling_picker/src/picker.rs index 396b05e..acdb8b5 100644 --- a/mingling_picker/src/picker.rs +++ b/mingling_picker/src/picker.rs @@ -226,7 +226,7 @@ impl<'a> ExactSizeIterator for PickerIter<'a> {} /// - `&[String]` (borrowed slice of owned strings) /// - `Vec<&str>` (owned vector of borrowed strings) /// - `Vec` (owned vector of owned strings) -pub trait IntoPicker<'a, Route> { +pub trait IntoPicker<'a> { /// Converts the value into a `Picker` /// /// # Examples @@ -243,13 +243,13 @@ pub trait IntoPicker<'a, Route> { /// let args: Picker = vec!["a".to_string(), "b".to_string()].to_picker(); /// assert_eq!(args.len(), 2); /// ``` - fn to_picker(self) -> Picker<'a, Route>; + fn to_picker(self) -> Picker<'a, ()>; /// Creates a `PickerPattern1` from the given flag for the `pick` method. /// /// This method converts the value into a `Picker` and starts a parameter /// picking chain with one flag. The result is initially `Unparsed`. - fn pick(self, flag: &'a PickerFlag<'a, N>) -> PickerPattern1<'a, N, Route> + fn pick(self, flag: &'a PickerFlag<'a, N>) -> PickerPattern1<'a, N, ()> where Self: Sized, N: Pickable<'a> + Default + Sized, @@ -264,10 +264,25 @@ pub trait IntoPicker<'a, Route> { error_route: None, } } + + /// Converts the value into a `Picker` with a specified route type. + /// + /// This method allows changing the route (phantom type parameter) of the picker. + /// The route type is typically used to distinguish different parsing contexts or + /// to carry compile-time state information through the picking chain. + fn with_route(self) -> Picker<'a, NewRoute> + where + Self: Sized, + { + Picker { + route_phantom: PhantomData, + args: self.to_picker().args, + } + } } -impl<'a, Route> IntoPicker<'a, Route> for &'a [&'a str] { - fn to_picker(self) -> Picker<'a, Route> { +impl<'a> IntoPicker<'a> for &'a [&'a str] { + fn to_picker(self) -> Picker<'a, ()> { Picker { route_phantom: PhantomData, args: PickerArgs::Slice(self), @@ -275,8 +290,8 @@ impl<'a, Route> IntoPicker<'a, Route> for &'a [&'a str] { } } -impl<'a, Route> IntoPicker<'a, Route> for &'a [String] { - fn to_picker(self) -> Picker<'a, Route> { +impl<'a> IntoPicker<'a> for &'a [String] { + fn to_picker(self) -> Picker<'a, ()> { let vec: Vec<&str> = self.iter().map(|s| s.as_str()).collect(); Picker { route_phantom: PhantomData, @@ -285,8 +300,8 @@ impl<'a, Route> IntoPicker<'a, Route> for &'a [String] { } } -impl<'a, Route> IntoPicker<'a, Route> for Vec<&'a str> { - fn to_picker(self) -> Picker<'a, Route> { +impl<'a> IntoPicker<'a> for Vec<&'a str> { + fn to_picker(self) -> Picker<'a, ()> { Picker { route_phantom: PhantomData, args: PickerArgs::Vec(self), @@ -294,8 +309,8 @@ impl<'a, Route> IntoPicker<'a, Route> for Vec<&'a str> { } } -impl<'a, Route> IntoPicker<'a, Route> for Vec { - fn to_picker(self) -> Picker<'a, Route> { +impl<'a> IntoPicker<'a> for Vec { + fn to_picker(self) -> Picker<'a, ()> { Picker { route_phantom: PhantomData, args: PickerArgs::Owned(self), diff --git a/mingling_picker/src/picker/patterns.rs b/mingling_picker/src/picker/patterns.rs index 1b21d32..20faadd 100644 --- a/mingling_picker/src/picker/patterns.rs +++ b/mingling_picker/src/picker/patterns.rs @@ -87,6 +87,32 @@ internal_repeat!(1..=32 => { self } + + /// Resets the route for this picker pattern, allowing a different route type. + /// + /// This method converts the current `PickerPattern` into a new one with a different + /// route type `NewRoute`. All existing flag configurations, defaults, and post- + /// processing functions are preserved, but the `error_route` and individual + /// `route_$` fields are cleared (set to `None`). + /// + /// This is useful when you want to change the error/redirect route type mid-chain, + /// for example when composing patterns from different contexts that use different + /// route enums. + #[allow(clippy::type_complexity)] + pub fn with_route(self) -> PickerPattern$<'a, (T$,+), NewRoute> { + PickerPattern$ { + args: self.args, + error_route: None, + ( + flag_$: self.flag_$, + result_$: self.result_$, + default_$: self.default_$, + route_$: None, + post_$: self.post_$, + +) + } + } + /// Attaches a post-processing function to this flag. /// /// After the flag's value is parsed (or defaulted), the given closure will be -- cgit