aboutsummaryrefslogtreecommitdiff
path: root/arg_picker/src/picker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'arg_picker/src/picker.rs')
-rw-r--r--arg_picker/src/picker.rs543
1 files changed, 0 insertions, 543 deletions
diff --git a/arg_picker/src/picker.rs b/arg_picker/src/picker.rs
deleted file mode 100644
index e8256ce..0000000
--- a/arg_picker/src/picker.rs
+++ /dev/null
@@ -1,543 +0,0 @@
-// Doc Not Optimize
-use std::{marker::PhantomData, ops::Index};
-
-mod parse;
-
-mod patterns;
-pub use patterns::*;
-
-mod result;
-pub use result::*;
-
-use crate::{Pickable, PickerArg, PickerArgResult};
-
-#[doc = include_str!("../README.md")]
-pub struct Picker<'a, Route = ()> {
- pub(crate) route_phantom: PhantomData<Route>,
-
- /// Internal arguments of Picker
- pub(crate) args: PickerArgs<'a>,
-}
-
-impl<'a> Picker<'a> {
- /// Creates a new `Picker` from the command-line arguments (excluding the program name).
- ///
- /// This is equivalent to calling `std::env::args().skip(1)`, which
- /// collects all arguments passed to the program except the first one
- /// (the executable path).
- #[must_use]
- pub fn from_args() -> Self {
- Self::from_args_skip(1)
- }
-
- /// Creates a new `Picker` from the command-line arguments, skipping the
- /// first `skip` entries.
- ///
- /// This method is useful when you want more control over which arguments
- /// are included. For example, pass `skip = 2` to skip both the program
- /// name and the first argument.
- #[must_use]
- pub fn from_args_skip(skip: usize) -> Self {
- let args = std::env::args().skip(skip).collect::<Vec<String>>();
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Owned(args),
- }
- }
-
- /// Changes the route (phantom type parameter) of the `Picker`.
- ///
- /// This method allows converting a `Picker` from one route type to another,
- /// while preserving the same underlying arguments. The route type is typically
- /// used to distinguish different parsing contexts or to carry compile-time
- /// state information through the picking chain.
- #[must_use]
- pub fn with_route<NewRoute>(self) -> Picker<'a, NewRoute>
- where
- Self: Sized,
- {
- Picker {
- route_phantom: PhantomData,
- args: self.args,
- }
- }
-}
-
-/// Internal arguments of Picker
-///
-/// - `Slice` - borrowed slice of string slices
-/// - `Vec` - owned vector of borrowed string slices
-/// - `Owned` - owned vector of owned strings
-pub enum PickerArgs<'a> {
- /// Borrowed slice of string slices
- Slice(&'a [&'a str]),
- /// Owned vector of borrowed string slices
- Vec(Vec<&'a str>),
- /// Owned vector of owned strings
- Owned(Vec<String>),
-}
-
-impl<'a> From<PickerArgs<'a>> for Vec<String> {
- fn from(value: PickerArgs<'a>) -> Self {
- match value {
- PickerArgs::Slice(items) => items.iter().map(ToString::to_string).collect(),
- PickerArgs::Vec(items) => items.into_iter().map(ToString::to_string).collect(),
- PickerArgs::Owned(items) => items,
- }
- }
-}
-
-impl<'a> From<&'a PickerArgs<'a>> for Vec<&'a str> {
- fn from(value: &'a PickerArgs<'a>) -> Self {
- match value {
- PickerArgs::Slice(items) => items.to_vec(),
- PickerArgs::Vec(items) => items.clone(),
- PickerArgs::Owned(items) => items.iter().map(String::as_str).collect(),
- }
- }
-}
-
-impl Default for PickerArgs<'_> {
- fn default() -> Self {
- Self::Vec(vec![])
- }
-}
-
-impl<'a> PickerArgs<'a> {
- /// Returns the number of arguments.
- #[must_use]
- pub const fn len(&self) -> usize {
- match self {
- PickerArgs::Slice(items) => items.len(),
- PickerArgs::Vec(items) => items.len(),
- PickerArgs::Owned(items) => items.len(),
- }
- }
-
- /// Returns `true` if there are no arguments.
- #[must_use]
- pub const fn is_empty(&self) -> bool {
- self.len() == 0
- }
-
- /// Returns an iterator over the arguments, yielding `&str` values.
- #[must_use]
- pub fn iter(&'a self) -> PickerIter<'a> {
- match self {
- PickerArgs::Slice(items) => PickerIter::Slice(items.iter()),
- PickerArgs::Vec(items) => PickerIter::Vec(items.iter()),
- PickerArgs::Owned(items) => PickerIter::Owned(items.iter()),
- }
- }
-
- /// Returns a reference to the argument at `index`, if it exists.
- #[must_use]
- pub fn get(&self, index: usize) -> Option<&str> {
- match self {
- PickerArgs::Slice(items) => items.get(index).copied(),
- PickerArgs::Vec(items) => items.get(index).copied(),
- PickerArgs::Owned(items) => items.get(index).map(String::as_str),
- }
- }
-}
-
-impl Index<usize> for PickerArgs<'_> {
- type Output = str;
-
- fn index(&self, index: usize) -> &Self::Output {
- match self {
- PickerArgs::Slice(items) => items[index],
- PickerArgs::Vec(items) => items[index],
- PickerArgs::Owned(items) => &items[index],
- }
- }
-}
-
-impl<'a> IntoIterator for &'a PickerArgs<'a> {
- type Item = &'a str;
- type IntoIter = PickerIter<'a>;
-
- fn into_iter(self) -> Self::IntoIter {
- match self {
- PickerArgs::Slice(items) => PickerIter::Slice(items.iter()),
- PickerArgs::Vec(items) => PickerIter::Vec(items.iter()),
- PickerArgs::Owned(items) => PickerIter::Owned(items.iter()),
- }
- }
-}
-
-impl<'a, Route> From<PickerArgs<'a>> for Picker<'a, Route> {
- fn from(args: PickerArgs<'a>) -> Self {
- Picker {
- route_phantom: PhantomData,
- args,
- }
- }
-}
-
-impl<'a, Route> From<&'a [&'a str]> for Picker<'a, Route> {
- fn from(value: &'a [&'a str]) -> Self {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Slice(value),
- }
- }
-}
-
-impl<'a, Route> From<Vec<&'a str>> for Picker<'a, Route> {
- fn from(value: Vec<&'a str>) -> Self {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Vec(value),
- }
- }
-}
-
-impl<Route> From<Vec<String>> for Picker<'_, Route> {
- fn from(value: Vec<String>) -> Self {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Owned(value),
- }
- }
-}
-
-impl<'a, Route> Picker<'a, Route> {
- /// Returns a reference to the internal `PickerArgs`.
- #[must_use]
- pub const fn args(&self) -> &PickerArgs<'a> {
- &self.args
- }
-
- /// Returns a mutable reference to the internal `PickerArgs`.
- pub const fn args_mut(&mut self) -> &mut PickerArgs<'a> {
- &mut self.args
- }
-
- /// Consumes `self` and returns the internal `PickerArgs`.
- #[must_use]
- pub fn into_args(self) -> PickerArgs<'a> {
- self.args
- }
-
- /// Returns the number of arguments.
- #[must_use]
- pub const fn len(&self) -> usize {
- self.args.len()
- }
-
- /// Returns `true` if there are no arguments.
- #[must_use]
- pub const fn is_empty(&self) -> bool {
- self.args.is_empty()
- }
-
- /// Returns an iterator over the arguments, yielding `&str` values.
- #[must_use]
- pub fn iter(&'a self) -> PickerIter<'a> {
- self.args.iter()
- }
-}
-
-impl Index<usize> for Picker<'_> {
- type Output = str;
-
- fn index(&self, index: usize) -> &Self::Output {
- &self.args[index]
- }
-}
-
-impl<'a, Route> Index<usize> for &'a Picker<'a, Route> {
- type Output = str;
-
- fn index(&self, index: usize) -> &Self::Output {
- &self.args[index]
- }
-}
-
-impl<'a, Route> IntoIterator for &'a Picker<'a, Route> {
- type Item = &'a str;
- type IntoIter = PickerIter<'a>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.args.iter()
- }
-}
-
-/// Iterator for `Picker` (and `PickerArgs`), yielding `&'a str` values.
-pub enum PickerIter<'a> {
- /// Iterates over a borrowed slice (`&[&str]`)
- Slice(std::slice::Iter<'a, &'a str>),
- /// Iterates over an owned vector of borrowed string slices (`Vec<&str>`)
- Vec(std::slice::Iter<'a, &'a str>),
- /// Iterates over an owned vector of owned strings (`Vec<String>`)
- Owned(std::slice::Iter<'a, String>),
-}
-
-impl<'a> Iterator for PickerIter<'a> {
- type Item = &'a str;
-
- fn next(&mut self) -> Option<Self::Item> {
- match self {
- PickerIter::Slice(iter) | PickerIter::Vec(iter) => iter.next().copied(),
- PickerIter::Owned(iter) => iter.next().map(String::as_str),
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- match self {
- PickerIter::Slice(iter) | PickerIter::Vec(iter) => iter.size_hint(),
- PickerIter::Owned(iter) => iter.size_hint(),
- }
- }
-}
-
-impl ExactSizeIterator for PickerIter<'_> {}
-
-impl<'a, Route> Picker<'a, Route> {
- /// Creates a `PickerPattern1` from the given arg to start a picking chain.
- ///
- /// This method initiates a parameter picking chain with one arg.
- /// The result is initially `Unparsed`.
- pub fn pick<N>(self, arg: impl Into<&'a PickerArg<'a, N>>) -> PickerPattern1<'a, N, Route>
- where
- N: Pickable<'a>,
- {
- Self::build_pattern1(self.args, arg.into(), None::<Route>)
- }
-
- /// Creates a `PickerPattern1` from the given arg.
- /// If parsing fails, attempts the fallback arg.
- pub fn pick_or<N, F>(
- self,
- arg: impl Into<&'a PickerArg<'a, N>>,
- or_arg: F,
- ) -> PickerPattern1<'a, N, Route>
- where
- N: Pickable<'a>,
- F: FnMut() -> N + 'static,
- {
- self.pick(arg).or(or_arg)
- }
-
- /// Creates a `PickerPattern1` from the given arg.
- /// If parsing fails, uses the provided default value.
- pub fn pick_or_default<N>(
- self,
- arg: impl Into<&'a PickerArg<'a, N>>,
- ) -> PickerPattern1<'a, N, Route>
- where
- N: Pickable<'a> + Default,
- {
- self.pick(arg).or_default()
- }
-
- /// Creates a `PickerPattern1` from the given arg.
- /// If parsing fails, switches to the given error route.
- pub fn pick_or_route<N, F>(
- self,
- arg: impl Into<&'a PickerArg<'a, N>>,
- error_route: F,
- ) -> PickerPattern1<'a, N, Route>
- where
- N: Pickable<'a>,
- F: FnMut() -> Route + 'static,
- {
- self.pick(arg).or_route(error_route)
- }
-}
-
-/// Trait for converting types into a `Picker`
-///
-/// Implemented for:
-/// - `&[&str]` (borrowed slice)
-/// - `&[String]` (borrowed slice of owned strings)
-/// - `Vec<&str>` (owned vector of borrowed strings)
-/// - `Vec<String>` (owned vector of owned strings)
-pub trait IntoPicker<'a> {
- /// Converts the value into a `Picker`
- ///
- /// # Examples
- ///
- /// ```
- /// use arg_picker::{IntoPicker, Picker};
- ///
- /// let args: Picker = (&["hello", "world"][..]).to_picker();
- /// assert_eq!(args.len(), 2);
- ///
- /// let args: Picker = vec!["foo", "bar"].to_picker();
- /// assert_eq!(args.len(), 2);
- ///
- /// let args: Picker = vec!["a".to_string(), "b".to_string()].to_picker();
- /// assert_eq!(args.len(), 2);
- /// ```
- fn to_picker(self) -> Picker<'a, ()>;
-
- /// Creates a `PickerPattern1` from the given arg for the `pick` method.
- ///
- /// This method converts the value into a `Picker` and starts a parameter
- /// picking chain with one arg. The result is initially `Unparsed`.
- fn pick<N>(self, arg: impl Into<&'a PickerArg<'a, N>>) -> PickerPattern1<'a, N, ()>
- where
- Self: Sized,
- N: Pickable<'a> + Sized,
- {
- Picker::build_pattern1(self.to_picker().args, arg.into(), None::<()>)
- }
-
- /// Starts building a picker pattern with the first argument, using a default value provider.
- ///
- /// This is a shorthand for calling `.pick(arg).or(func)`.
- ///
- /// # Type Parameters
- ///
- /// * `Next` — The nominal type of the first argument; must implement [`Pickable`].
- ///
- /// # Parameters
- ///
- /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`].
- /// * `func` — A closure that provides a default value if the arg is not provided by the user.
- fn pick_or<Next, F>(
- self,
- arg: impl Into<&'a PickerArg<'a, Next>>,
- func: F,
- ) -> PickerPattern1<'a, Next, ()>
- where
- Self: Sized,
- Next: Pickable<'a> + Sized,
- F: FnMut() -> Next + 'static,
- {
- self.pick(arg).or(func)
- }
-
- /// Starts building a picker pattern with the first argument, using a default value.
- ///
- /// This is a shorthand for calling `.pick(arg).or_default()`.
- ///
- /// # Type Parameters
- ///
- /// * `Next` — The nominal type of the first argument; must implement [`Pickable`] and [`Default`].
- ///
- /// # Parameters
- ///
- /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`].
- fn pick_or_default<Next>(
- self,
- arg: impl Into<&'a PickerArg<'a, Next>>,
- ) -> PickerPattern1<'a, Next, ()>
- where
- Self: Sized,
- Next: Pickable<'a> + Default + Sized,
- {
- self.pick(arg).or_default()
- }
-
- /// Starts building a picker pattern with the first argument, using a route if the arg is not provided.
- ///
- /// This is a shorthand for calling `.pick(arg).or_route(func)`.
- ///
- /// # Type Parameters
- ///
- /// * `Next` — The nominal type of the first argument; must implement [`Pickable`].
- ///
- /// # Parameters
- ///
- /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`].
- /// * `func` — A closure that produces a route value if the arg is not provided by the user.
- fn pick_or_route<Next, F, Route>(
- self,
- arg: impl Into<&'a PickerArg<'a, Next>>,
- func: F,
- ) -> PickerPattern1<'a, Next, Route>
- where
- Self: Sized,
- Next: Pickable<'a> + Sized,
- F: FnMut() -> Route + 'static,
- {
- self.pick(arg).with_route::<Route>().or_route(func)
- }
-
- /// Converts the value into a `Picker` with a specified route type.
- ///
- /// This method allows changing the route (phantom type parameter) of the picker.
- /// The route type is typically used to distinguish different parsing contexts or
- /// to carry compile-time state information through the picking chain.
- fn with_route<NewRoute>(self) -> Picker<'a, NewRoute>
- where
- Self: Sized,
- {
- Picker {
- route_phantom: PhantomData,
- args: self.to_picker().args,
- }
- }
-}
-
-impl<'a> IntoPicker<'a> for &'a [&'a str] {
- fn to_picker(self) -> Picker<'a, ()> {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Slice(self),
- }
- }
-}
-
-impl<'a> IntoPicker<'a> for &'a [String] {
- fn to_picker(self) -> Picker<'a, ()> {
- let vec: Vec<&str> = self.iter().map(String::as_str).collect();
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Vec(vec),
- }
- }
-}
-
-impl<'a> IntoPicker<'a> for Vec<&'a str> {
- fn to_picker(self) -> Picker<'a, ()> {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Vec(self),
- }
- }
-}
-
-impl<'a> IntoPicker<'a> for &'a Vec<String> {
- fn to_picker(self) -> Picker<'a, ()> {
- let slice: Vec<&str> = self.iter().map(String::as_str).collect();
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Vec(slice),
- }
- }
-}
-
-impl<'a> IntoPicker<'a> for Vec<String> {
- fn to_picker(self) -> Picker<'a, ()> {
- Picker {
- route_phantom: PhantomData,
- args: PickerArgs::Owned(self),
- }
- }
-}
-
-impl<'a, Route> Picker<'a, Route> {
- /// Build the `PickerPattern` via Arguments
- pub fn build_pattern1<N>(
- args: PickerArgs<'a>,
- arg: &'a PickerArg<'a, N>,
- error_route: Option<Route>,
- ) -> PickerPattern1<'a, N, Route>
- where
- N: Pickable<'a>,
- {
- PickerPattern1 {
- args,
- error_route,
- arg_1: arg,
- result_1: PickerArgResult::Unparsed,
- route_1: None,
- default_1: None,
- post_1: None,
- }
- }
-}