diff options
| -rw-r--r-- | mingling_picker/src/picker/patterns.rs | 22 | ||||
| -rw-r--r-- | mingling_picker/src/requirement.rs | 48 | ||||
| -rw-r--r-- | mingling_picker_macros/src/req.rs | 63 |
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() |
