aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-14 05:53:35 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-14 05:55:17 +0800
commit6518a3221160c4371b16f793b87975067c409ac9 (patch)
tree44ce4312bfad9c1c14c8e29fb448b9972bf14bc4
parent93a1df3569fd5737089bd14f446fd7f91daeaa74 (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.rs3
-rw-r--r--mingling_picker/src/picker/parse.rs17
-rw-r--r--mingling_picker/src/result.rs222
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(),
+ }
+ }
+}