aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-14 02:17:33 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-14 02:17:33 +0800
commitde370df01a171b4fd910dfa9a067830acd1f9a3c (patch)
tree53350a4cdaa93437da6f06916ac371f82e79c57b
parent62f6b476284da67efc55483a81b57f99a478702a (diff)
refactor(mingling_picker): move parse result out of requirement and into
pattern BREAKING CHANGE: `PickerRequirement` no longer stores a `PickerResult`. Parsed results are now held in the `PickerPattern` structs. The `result`, `result_mut`, `set_result`, `reset_result`, and `with_result` methods on `PickerRequirement` have been removed. The `Picker::pick` method is introduced to begin a pattern definition.
-rw-r--r--mingling_picker/src/picker/patterns.rs22
-rw-r--r--mingling_picker/src/requirement.rs48
-rw-r--r--mingling_picker_macros/src/req.rs63
3 files changed, 60 insertions, 73 deletions
diff --git a/mingling_picker/src/picker/patterns.rs b/mingling_picker/src/picker/patterns.rs
index 74a8cd8..80632d5 100644
--- a/mingling_picker/src/picker/patterns.rs
+++ b/mingling_picker/src/picker/patterns.rs
@@ -1,12 +1,26 @@
-use crate::{Pickable, PickerArguments, PickerRequirement};
+use crate::{Pickable, Picker, PickerArguments, PickerRequirement, PickerResult};
mingling_picker_macros::internal_repeat! (1..=32 => {
- pub struct PickerPattern$<'a, (Type$,)+>
- where (Type$: Pickable + Default,)+
+ pub struct PickerPattern$<'a, (T$,)+>
+ where (T$: Pickable + Default,)+
{
pub args: PickerArguments<'a>,
(
- pub require_$: PickerRequirement<'a, Type$>,
+ pub require_$: &'a PickerRequirement<'a, T$>,
+ pub result_$: PickerResult<T$>,
)+
}
});
+
+impl<'a> Picker<'a> {
+ pub fn pick<N>(self, req: &'a PickerRequirement<'a, N>) -> PickerPattern1<'a, N>
+ where
+ N: Pickable + Default,
+ {
+ PickerPattern1 {
+ args: self.args,
+ require_1: req,
+ result_1: PickerResult::Unparsed,
+ }
+ }
+}
diff --git a/mingling_picker/src/requirement.rs b/mingling_picker/src/requirement.rs
index 32fefff..564ae45 100644
--- a/mingling_picker/src/requirement.rs
+++ b/mingling_picker/src/requirement.rs
@@ -1,4 +1,5 @@
-use crate::{Pickable, PickerResult};
+use crate::Pickable;
+use std::marker::PhantomData;
/// Represents a constraint definition for a parameter selection.
///
@@ -19,25 +20,23 @@ use crate::{Pickable, PickerResult};
/// than by a `--name` or `-n` flag.
/// - `false`: The parameter is a named (flag-based) parameter.
///
-/// - `result`: The parsed result of this parameter requirement. Initially set to
-/// `PickerResult::Unparsed`. After parsing, contains either the successfully parsed value or an
-/// error.
-#[derive(Default)]
+/// - `_type`: PhantomData to hold the type parameter.
+#[derive(Default, Clone, Copy)]
pub struct PickerRequirement<'a, Type>
where
Type: Default + Pickable,
{
/// Full name, may include variant names (aliases), e.g., `["config", "cfg"]`.
- full: &'a [&'a str],
+ pub full: &'a [&'a str],
/// Short name, e.g., `'c'`.
- short: Option<char>,
+ pub short: Option<char>,
/// Whether the parameter is positional (no flag, matched by position).
- positional: bool,
+ pub positional: bool,
- /// The parsed result of this parameter requirement.
- result: PickerResult<Type>,
+ /// PhantomData to hold the type parameter.
+ pub internal_type: PhantomData<Type>,
}
impl<'a, Type> PickerRequirement<'a, Type>
@@ -50,7 +49,7 @@ where
full,
short,
positional,
- result: PickerResult::Unparsed,
+ internal_type: PhantomData,
}
}
@@ -120,31 +119,4 @@ where
self.positional = positional;
self
}
-
- /// Returns a reference to the current parse result.
- pub fn result(&self) -> &PickerResult<Type> {
- &self.result
- }
-
- /// Returns a mutable reference to the current parse result.
- pub fn result_mut(&mut self) -> &mut PickerResult<Type> {
- &mut self.result
- }
-
- /// Sets the parse result.
- pub fn set_result(&mut self, result: PickerResult<Type>) {
- self.result = result;
- }
-
- /// Replaces the parse result with `PickerResult::Unparsed` and returns self.
- pub fn reset_result(mut self) -> Self {
- self.result = PickerResult::Unparsed;
- self
- }
-
- /// Sets the parse result and returns self.
- pub fn with_result(mut self, result: PickerResult<Type>) -> Self {
- self.result = result;
- self
- }
}
diff --git a/mingling_picker_macros/src/req.rs b/mingling_picker_macros/src/req.rs
index 1c3bb99..35c9027 100644
--- a/mingling_picker_macros/src/req.rs
+++ b/mingling_picker_macros/src/req.rs
@@ -68,50 +68,51 @@ pub(crate) fn req(input: TokenStream) -> TokenStream {
None => aliases,
};
- // Generate code
- let import = quote! { ::mingling::picker::PickerRequirement };
-
- // Type parameter
- let ty_ts: TS2 = ty
- .map(|t| {
- let ts: TokenStream = t.iter().cloned().collect();
- ts.to_string().parse().unwrap()
- })
- .unwrap_or(TS2::new());
-
- let with_type = if ty.is_some() {
- quote! { #import::<#ty_ts> }
- } else {
- quote! { #import::<_> }
+ let path: TS2 = {
+ let ty_ts: TS2 = ty
+ .map(|t| {
+ let ts: TokenStream = t.iter().cloned().collect();
+ ts.to_string().parse().unwrap()
+ })
+ .unwrap_or(TS2::new());
+
+ let import = quote! { ::mingling::picker::PickerRequirement };
+ if ty.is_some() {
+ quote! { #import::<#ty_ts> }
+ } else {
+ quote! { #import::<_> }
+ }
};
- // .with_full(...)
- let with_full = if !full_names.is_empty() {
+ // full: &["name", "alias", ...] or &[]
+ let full_value: TS2 = if !full_names.is_empty() {
let strs: Vec<proc_macro2::Literal> = full_names
.iter()
.map(|s| proc_macro2::Literal::string(s))
.collect();
- quote! { .with_full(&[#(#strs),*]) }
+ quote! { &[#(#strs),*] }
} else {
- TS2::new()
+ quote! { &[] }
};
- // .with_short(...)
- let with_short = short_char
- .map(|c| {
+ // short: Some('c') or None
+ let short_value: TS2 = match short_char {
+ Some(c) => {
let lit = proc_macro2::Literal::character(c);
- quote! { .with_short(#lit) }
- })
- .unwrap_or_default();
+ quote! { ::std::option::Option::Some(#lit) }
+ }
+ None => quote! { ::std::option::Option::None },
+ };
- // .with_positional(...)
- let pos = !is_named;
+ let positional_value: bool = !is_named;
let result = quote! {
- #with_type::default()
- #with_full
- #with_short
- .with_positional(#pos)
+ #path {
+ full: #full_value,
+ short: #short_value,
+ positional: #positional_value,
+ internal_type: ::std::marker::PhantomData,
+ }
};
result.into()