aboutsummaryrefslogtreecommitdiff
path: root/mingling_picker/src/picker/parse.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-17 11:08:07 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-17 11:11:28 +0800
commit79ec6878877f0fd9246d67d3cd4f8cc2d1200150 (patch)
treee3cd8cfc7ef5cd2a6a7ceb93d9a4b1764fa21b61 /mingling_picker/src/picker/parse.rs
parente6136f22cff446b16dbebf3b26a6fdea6dbc0e83 (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.rs177
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
- }
- }
-});