From 6518a3221160c4371b16f793b87975067c409ac9 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 14 Jul 2026 05:53:35 +0800 Subject: feat(mingling_picker): rename FormatError to ParseError and add parse module Remove unnecessary Pickable trait bounds on PickerResult and its From implementations. Introduce a new `parse` module with macro-generated parse stubs for up to 32 tuple types. --- mingling_picker/src/picker.rs | 3 + mingling_picker/src/picker/parse.rs | 17 +++ mingling_picker/src/result.rs | 222 +++++++++++++++++++++++++++++++++--- 3 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 mingling_picker/src/picker/parse.rs diff --git a/mingling_picker/src/picker.rs b/mingling_picker/src/picker.rs index f5c2bd0..17a872d 100644 --- a/mingling_picker/src/picker.rs +++ b/mingling_picker/src/picker.rs @@ -1,5 +1,8 @@ use std::ops::{Deref, Index}; +mod parse; +// pub use parse::*; + mod patterns; pub use patterns::*; diff --git a/mingling_picker/src/picker/parse.rs b/mingling_picker/src/picker/parse.rs new file mode 100644 index 0000000..defbcbf --- /dev/null +++ b/mingling_picker/src/picker/parse.rs @@ -0,0 +1,17 @@ +use crate::{Pickable, PickerResult}; +use mingling_picker_macros::internal_repeat; + +internal_repeat!(1..=32 => { + use crate::PickerPattern$; +}); + +internal_repeat!(1..=32 => { + impl<'a, (T$,+)> PickerPattern$<'a, (T$,+)> + where (T$: Pickable + Default,+) + { + #[allow(clippy::type_complexity)] + pub fn parse(self) -> PickerResult<((T$,+))> { + todo!() + } + } +}); diff --git a/mingling_picker/src/result.rs b/mingling_picker/src/result.rs index 1fad4f5..f01bcc1 100644 --- a/mingling_picker/src/result.rs +++ b/mingling_picker/src/result.rs @@ -1,17 +1,12 @@ -use crate::Pickable; - /// Represents the result of parsing or looking up a value. /// /// This enum is generic over the type being parsed. It models four possible outcomes: /// - [`Unparsed`](PickerResult::Unparsed): The value has not yet been parsed (default). /// - [`Parsed`](PickerResult::Parsed): The value was successfully parsed into `Type`. /// - [`NotFound`](PickerResult::NotFound): The requested value could not be found. -/// - [`FormatError`](PickerResult::FormatError): The input could not be parsed due to a format error. +/// - [`ParseError`](PickerResult::ParseError): The input could not be parsed due to a format error. #[derive(Default)] -pub enum PickerResult -where - Type: Default + Pickable, -{ +pub enum PickerResult { /// The value has not yet been parsed (default). #[default] Unparsed, @@ -23,29 +18,23 @@ where NotFound, /// The input could not be parsed due to a format error. - FormatError, + ParseError, } -impl From> for PickerResult -where - Type: Default + Pickable, -{ +impl From> for PickerResult { /// Converts a `Result` into a `PickerResult`. /// /// - `Ok(value)` maps to [`Parsed(value)`](PickerResult::Parsed). - /// - `Err(_)` maps to [`FormatError`](PickerResult::FormatError). + /// - `Err(_)` maps to [`ParseError`](PickerResult::ParseError). fn from(result: Result) -> Self { match result { Ok(value) => PickerResult::Parsed(value), - Err(_) => PickerResult::FormatError, + Err(_) => PickerResult::ParseError, } } } -impl From> for PickerResult -where - Type: Default + Pickable, -{ +impl From> for PickerResult { /// Converts an `Option` into a `PickerResult`. /// /// - `Some(value)` maps to [`Parsed(value)`](PickerResult::Parsed). @@ -57,3 +46,200 @@ where } } } + +impl PickerResult { + /// Returns `true` if the result is [`Parsed`](PickerResult::Parsed). + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert!(result.is_parsed()); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert!(!result.is_parsed()); + /// ``` + pub fn is_parsed(&self) -> bool { + matches!(self, PickerResult::Parsed(_)) + } + + /// Returns `true` if the result is [`Parsed`](PickerResult::Parsed) or [`NotFound`](PickerResult::NotFound). + /// i.e., the value exists (was either found or not yet parsed, but not a parse error). + /// Typically indicates the value was "found" in some sense. + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert!(result.is_found()); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert!(result.is_found()); + /// + /// let result: PickerResult = PickerResult::ParseError; + /// assert!(!result.is_found()); + /// ``` + pub fn is_found(&self) -> bool { + matches!(self, PickerResult::Parsed(_) | PickerResult::NotFound) + } + + /// Returns `true` if the result is [`ParseError`](PickerResult::ParseError). + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::ParseError; + /// assert!(result.is_err()); + /// + /// let result: PickerResult = PickerResult::Parsed(10); + /// assert!(!result.is_err()); + /// ``` + pub fn is_err(&self) -> bool { + matches!(self, PickerResult::ParseError) + } + + /// Returns `Some(&Type)` if [`Parsed`](PickerResult::Parsed), otherwise `None`. + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert_eq!(result.parsed(), Some(&42)); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert_eq!(result.parsed(), None); + /// ``` + pub fn parsed(&self) -> Option<&Type> { + if let PickerResult::Parsed(value) = self { + Some(value) + } else { + None + } + } + + /// Returns the contained [`Parsed`](PickerResult::Parsed) value or panics with a given message. + /// + /// # Panics + /// Panics if the value is not [`Parsed`](PickerResult::Parsed), with a message including the provided `msg`. + /// + /// # Examples + /// + /// ```should_panic + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::NotFound; + /// result.expect("expected a parsed value"); + /// ``` + pub fn expect(self, msg: &str) -> Type { + match self { + PickerResult::Parsed(value) => value, + _ => panic!("{}", msg), + } + } + + /// Returns the contained [`Parsed`](PickerResult::Parsed) value or panics. + /// + /// # Panics + /// Panics if the value is not [`Parsed`](PickerResult::Parsed). + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap(), 42); + /// ``` + /// + /// ```should_panic + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::NotFound; + /// result.unwrap(); + /// ``` + pub fn unwrap(self) -> Type { + match self { + PickerResult::Parsed(value) => value, + PickerResult::Unparsed => { + panic!("called `PickerResult::unwrap()` on an `Unparsed` value") + } + PickerResult::NotFound => { + panic!("called `PickerResult::unwrap()` on a `NotFound` value") + } + PickerResult::ParseError => { + panic!("called `PickerResult::unwrap()` on a `ParseError` value") + } + } + } + + /// Returns the contained [`Parsed`](PickerResult::Parsed) value or a provided `default`. + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or(0), 42); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert_eq!(result.unwrap_or(0), 0); + /// ``` + pub fn unwrap_or(self, default: Type) -> Type { + match self { + PickerResult::Parsed(value) => value, + _ => default, + } + } + + /// Returns the contained [`Parsed`](PickerResult::Parsed) value or computes it from a closure. + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or_else(|| 0), 42); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert_eq!(result.unwrap_or_else(|| 0), 0); + /// ``` + pub fn unwrap_or_else Type>(self, f: F) -> Type { + match self { + PickerResult::Parsed(value) => value, + _ => f(), + } + } + + /// Returns the contained [`Parsed`](PickerResult::Parsed) value or the default value of `Type`. + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or_default(), 42); + /// + /// let result: PickerResult = PickerResult::NotFound; + /// assert_eq!(result.unwrap_or_default(), 0); + /// ``` + pub fn unwrap_or_default(self) -> Type + where + Type: Default, + { + match self { + PickerResult::Parsed(value) => value, + _ => Type::default(), + } + } +} -- cgit