diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-14 05:53:35 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-14 05:55:17 +0800 |
| commit | 6518a3221160c4371b16f793b87975067c409ac9 (patch) | |
| tree | 44ce4312bfad9c1c14c8e29fb448b9972bf14bc4 | |
| parent | 93a1df3569fd5737089bd14f446fd7f91daeaa74 (diff) | |
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.
| -rw-r--r-- | mingling_picker/src/picker.rs | 3 | ||||
| -rw-r--r-- | mingling_picker/src/picker/parse.rs | 17 | ||||
| -rw-r--r-- | mingling_picker/src/result.rs | 222 |
3 files changed, 224 insertions, 18 deletions
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<Type> -where - Type: Default + Pickable, -{ +pub enum PickerResult<Type> { /// 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<Type, E> From<Result<Type, E>> for PickerResult<Type> -where - Type: Default + Pickable, -{ +impl<Type, E> From<Result<Type, E>> for PickerResult<Type> { /// Converts a `Result<Type, E>` into a `PickerResult<Type>`. /// /// - `Ok(value)` maps to [`Parsed(value)`](PickerResult::Parsed). - /// - `Err(_)` maps to [`FormatError`](PickerResult::FormatError). + /// - `Err(_)` maps to [`ParseError`](PickerResult::ParseError). fn from(result: Result<Type, E>) -> Self { match result { Ok(value) => PickerResult::Parsed(value), - Err(_) => PickerResult::FormatError, + Err(_) => PickerResult::ParseError, } } } -impl<Type> From<Option<Type>> for PickerResult<Type> -where - Type: Default + Pickable, -{ +impl<Type> From<Option<Type>> for PickerResult<Type> { /// Converts an `Option<Type>` into a `PickerResult<Type>`. /// /// - `Some(value)` maps to [`Parsed(value)`](PickerResult::Parsed). @@ -57,3 +46,200 @@ where } } } + +impl<Type> PickerResult<Type> { + /// Returns `true` if the result is [`Parsed`](PickerResult::Parsed). + /// + /// # Examples + /// + /// ``` + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult<i32> = PickerResult::Parsed(42); + /// assert!(result.is_parsed()); + /// + /// let result: PickerResult<i32> = 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<i32> = PickerResult::Parsed(42); + /// assert!(result.is_found()); + /// + /// let result: PickerResult<i32> = PickerResult::NotFound; + /// assert!(result.is_found()); + /// + /// let result: PickerResult<i32> = 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<i32> = PickerResult::ParseError; + /// assert!(result.is_err()); + /// + /// let result: PickerResult<i32> = 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<i32> = PickerResult::Parsed(42); + /// assert_eq!(result.parsed(), Some(&42)); + /// + /// let result: PickerResult<i32> = 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<i32> = 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<i32> = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap(), 42); + /// ``` + /// + /// ```should_panic + /// use mingling_picker::PickerResult; + /// + /// let result: PickerResult<i32> = 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<i32> = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or(0), 42); + /// + /// let result: PickerResult<i32> = 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<i32> = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or_else(|| 0), 42); + /// + /// let result: PickerResult<i32> = PickerResult::NotFound; + /// assert_eq!(result.unwrap_or_else(|| 0), 0); + /// ``` + pub fn unwrap_or_else<F: FnOnce() -> 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<i32> = PickerResult::Parsed(42); + /// assert_eq!(result.unwrap_or_default(), 42); + /// + /// let result: PickerResult<i32> = 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(), + } + } +} |
