diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-17 11:08:07 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-17 11:11:28 +0800 |
| commit | 79ec6878877f0fd9246d67d3cd4f8cc2d1200150 (patch) | |
| tree | e3cd8cfc7ef5cd2a6a7ceb93d9a4b1764fa21b61 /mingling_picker/src/picker/parse.rs | |
| parent | e6136f22cff446b16dbebf3b26a6fdea6dbc0e83 (diff) | |
refactor: rename `mingling_picker` to `arg_picker`
Diffstat (limited to 'mingling_picker/src/picker/parse.rs')
| -rw-r--r-- | mingling_picker/src/picker/parse.rs | 177 |
1 files changed, 0 insertions, 177 deletions
diff --git a/mingling_picker/src/picker/parse.rs b/mingling_picker/src/picker/parse.rs deleted file mode 100644 index 698baac..0000000 --- a/mingling_picker/src/picker/parse.rs +++ /dev/null @@ -1,177 +0,0 @@ -// -------------------------------------------------------------------------------------------- -// I have to say, the code generated by this `internal_repeat!` macro is really UGLY. -// -// But I have to admit, this is a **trade-off**. To achieve the syntax of `pick().pick().pick()` -// while ensuring type safety, this is the best approach I could think of. -// -// P.S. If there's a better way, please let me know. Thanks! -// -------------------------------------------------------------------------------------------- -// -// Then, I must disable `clippy::type_complexity` — this guy is way too noisy. -#![allow(clippy::type_complexity)] - -use crate::{Pickable, PickerArgAttr, PickerArgInfo, PickerArgResult, PickerArgs, TagPhaseContext}; -use mingling_picker_macros::internal_repeat; - -internal_repeat!(1..=32 => { - use crate::PickerPattern$; - use crate::PickerResult$; -}); - -internal_repeat!(1..=32 => { - impl<'a, (T$,+), Route> PickerPattern$<'a, (T$,+), Route> - where (T$: Pickable<'a>,+) { - /// Unwraps the result, panicking if a route was selected. - /// - /// # Panics - /// - /// Panics if a route was selected. - pub fn unwrap(self) -> ((T$,+)) { - let p = self.parse(); - ((p.v$.unwrap(),+)) - } - - /// Returns the individual option values without checking the route. - pub fn unpack(self) -> ((Option<T$>,+)) { - let p = self.parse(); - ((p.v$,+)) - } - - /// Converts to a `Result`, returning `Err(route)` if a route was selected, - /// or `Ok(values)` otherwise. - pub fn to_result(self) -> Result<((T$,+)), Route> { - let p = self.parse(); - if let Some(r) = p.route { - return Err(r); - } - Ok(p.unwrap()) - } - - /// Converts to an `Option`, returning `None` if a route was selected, - /// or `Some(values)` otherwise. - pub fn to_option(self) -> Option<((T$,+))> { - let p = self.parse(); - if p.route.is_some() { - return None; - } - Some(p.unwrap()) - } - } -}); - -internal_repeat!(1..=32 => { - impl<'a, (T$,+), Route> PickerPattern$<'a, (T$,+), Route> - where (T$: Pickable<'a>,+) - { - pub fn parse(mut self) -> PickerResult$<(T$,+), Route> { - // ArgInfos - let arg_infos: [PickerArgInfo; $] = [ - ( - PickerArgInfo::from(self.arg_$), - +) - ]; - - let mut bundle: [ - ( - // Arg Attr - PickerArgAttr, - - // Tag Func - Box<dyn FnOnce(&PickerArgs<'a>, &[u8]) -> Vec<usize>>, - - // Pick Func - Box<dyn FnOnce(&[&str], &mut Option<Route>)>, - - // Index - usize - ) - ; $] = [ - ( - ( - // Arg Attr - T$::get_attr(self.arg_$), - - // Tag Func - Box::new(|args, mask| { - let ctx = TagPhaseContext { - arg_info: &arg_infos[$-], - args, - mask - }; - T$::tag(ctx) - }), - - // Pick Func - Box::new(|args, error_route| { - self.result_$ = match T$::pick(args) { - PickerArgResult::Parsed(mut value) => { - // Postprocess - if let Some(post) = self.post_$ { - value = post(value); - } - PickerArgResult::Parsed(value) - }, - other => { - if let Some(get_default) = self.default_$ { - let mut value = get_default(); - - // Postprocess - if let Some(post) = self.post_$ { - value = post(value); - } - - PickerArgResult::Parsed(value) - } else { - if error_route.is_none() { - if let Some(get_route) = self.route_$ { - *error_route = Some(get_route().into()); - } - } - other - } - }, - - } - }), - - // Index - $ - ), - +) - ]; - - // Sort by Bundle Ord (descending) - bundle.sort_by(|a, b| b.0.cmp(&a.0)); - - // Mask — size = number of args (not args), so use args length - let mut mask: Vec<u8> = vec![0u8; self.args.len()]; - - // Parsing - for (_, tag_func, pick_func, _idx) in bundle { - - // Tag phase - let tagged = tag_func(&self.args, mask.as_slice()); - let mut args_to_pick: Vec<&str> = vec![]; - - for i in tagged { - mask[i] = 1; - - // Update args to pick - args_to_pick.push(self.args.get(i).unwrap_or_default()); - } - - // Pick phase - pick_func(args_to_pick.as_slice(), &mut self.error_route); - } - - // Combine Result - let result: PickerResult$<(T$,+), Route> = PickerResult$ { - route: self.error_route, - ( - v$: self.result_$.to_option(), - +) - }; - result - } - } -}); |
