aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-10 16:52:19 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-10 16:52:19 +0800
commit02e07a18fcb3af9319c271f6e41d5b7785e2e436 (patch)
treeff76916c254e87a7aadc5cb4dfd2134eaf4f03fc
parent03b487f0f93ac32835149d4c1a0fb420341134f8 (diff)
style: satisfy clippy pedantic and nursery lints
-rw-r--r--arg_picker/src/arg.rs111
-rw-r--r--arg_picker/src/builtin/pick_flag.rs4
-rw-r--r--arg_picker/src/builtin/pick_ip_attr.rs39
-rw-r--r--arg_picker/src/builtin/pick_numbers.rs9
-rw-r--r--arg_picker/src/builtin/pick_pathbuf.rs10
-rw-r--r--arg_picker/src/builtin/pick_paths.rs22
-rw-r--r--arg_picker/src/builtin/pick_picker_args.rs2
-rw-r--r--arg_picker/src/builtin/pick_socket_attr.rs39
-rw-r--r--arg_picker/src/builtin/pick_string.rs5
-rw-r--r--arg_picker/src/infos.rs141
-rw-r--r--arg_picker/src/lib.rs4
-rw-r--r--arg_picker/src/parselib.rs20
-rw-r--r--arg_picker/src/parselib/arg_matcher.rs4
-rw-r--r--arg_picker/src/parselib/flag_matcher.rs8
-rw-r--r--arg_picker/src/parselib/multi_arg_matcher.rs4
-rw-r--r--arg_picker/src/parselib/pos_matcher.rs2
-rw-r--r--arg_picker/src/parselib/single_matcher.rs7
-rw-r--r--arg_picker/src/parselib/style.rs38
-rw-r--r--arg_picker/src/parselib/utils.rs30
-rw-r--r--arg_picker/src/pickable/multi_pickable.rs6
-rw-r--r--arg_picker/src/picker.rs62
-rw-r--r--arg_picker/src/picker/patterns.rs11
-rw-r--r--arg_picker/src/value/flag.rs18
-rw-r--r--arg_picker/src/value/paths.rs21
-rw-r--r--arg_picker/src/value/vec_until.rs9
25 files changed, 322 insertions, 304 deletions
diff --git a/arg_picker/src/arg.rs b/arg_picker/src/arg.rs
index 32824ea..c36fba4 100644
--- a/arg_picker/src/arg.rs
+++ b/arg_picker/src/arg.rs
@@ -20,7 +20,7 @@ use std::marker::PhantomData;
/// than by a `--name` or `-n` flag.
/// - `false`: The parameter is a named (flag-based) parameter.
///
-/// - `_type`: PhantomData to hold the type parameter.
+/// - `_type`: [`PhantomData`] to hold the type parameter.
#[derive(Default, Clone, Copy)]
pub struct PickerArg<'a, Type>
where
@@ -35,16 +35,16 @@ where
/// Whether the parameter is positional (no flag, matched by position).
pub positional: bool,
- /// PhantomData to hold the type parameter.
+ /// [`PhantomData`] to hold the type parameter.
pub internal_type: PhantomData<Type>,
}
-impl<'a, Type> From<&'a PickerArg<'a, Type>> for PickerArg<'a, Type>
+impl<'a, Type> From<&'a Self> for PickerArg<'a, Type>
where
Type: Pickable<'a>,
{
- fn from(value: &'a PickerArg<'a, Type>) -> Self {
- PickerArg {
+ fn from(value: &'a Self) -> Self {
+ Self {
full: value.full,
short: value.short,
positional: value.positional,
@@ -58,7 +58,8 @@ where
Type: Pickable<'a>,
{
/// Creates a new `PickerArg` with the provided parameters.
- pub fn new(full: &'a [&'a str], short: Option<char>, positional: bool) -> Self {
+ #[must_use]
+ pub const fn new(full: &'a [&'a str], short: Option<char>, positional: bool) -> Self {
Self {
full,
short,
@@ -68,12 +69,14 @@ where
}
/// Returns the full name list (including aliases).
- pub fn full(&self) -> &'a [&'a str] {
+ #[must_use]
+ pub const fn full(&self) -> &'a [&'a str] {
self.full
}
/// Returns the short name, if any.
- pub fn short(&self) -> Option<char> {
+ #[must_use]
+ pub const fn short(&self) -> Option<char> {
self.short
}
@@ -81,7 +84,8 @@ where
///
/// If `full` is empty or `short` is `None`, the parameter is considered positional
/// regardless of the stored value.
- pub fn is_positional(&self) -> bool {
+ #[must_use]
+ pub const fn is_positional(&self) -> bool {
if self.full.is_empty() && self.short.is_none() {
true
} else {
@@ -90,46 +94,51 @@ where
}
/// Sets the full name list.
- pub fn set_full(&mut self, full: &'a [&'a str]) {
+ pub const fn set_full(&mut self, full: &'a [&'a str]) {
self.full = full;
}
/// Sets the short name.
- pub fn set_short(&mut self, short: Option<char>) {
+ pub const fn set_short(&mut self, short: Option<char>) {
self.short = short;
}
/// Sets whether the parameter is positional.
- pub fn set_positional(&mut self, positional: bool) {
+ pub const fn set_positional(&mut self, positional: bool) {
self.positional = positional;
}
/// Sets the full name list and returns self.
- pub fn with_full(mut self, full: &'a [&'a str]) -> Self {
+ #[must_use]
+ pub const fn with_full(mut self, full: &'a [&'a str]) -> Self {
self.full = full;
self
}
/// Clears the full name list (sets it to an empty slice) and returns self.
- pub fn without_full(mut self) -> Self {
+ #[must_use]
+ pub const fn without_full(mut self) -> Self {
self.full = &[];
self
}
/// Sets the short name to the given character and returns self.
- pub fn with_short(mut self, short: char) -> Self {
+ #[must_use]
+ pub const fn with_short(mut self, short: char) -> Self {
self.short = Some(short);
self
}
/// Clears the short name (sets it to None) and returns self.
- pub fn without_short(mut self) -> Self {
+ #[must_use]
+ pub const fn without_short(mut self) -> Self {
self.short = None;
self
}
/// Sets whether the parameter is positional and returns self.
- pub fn with_positional(mut self, positional: bool) -> Self {
+ #[must_use]
+ pub const fn with_positional(mut self, positional: bool) -> Self {
self.positional = positional;
self
}
@@ -137,19 +146,19 @@ where
/// Converts this `PickerArg` into a `PickerArgInfo` value.
///
/// This is a convenience method equivalent to calling `PickerArgInfo::from(self)`.
+ #[must_use]
pub fn into_info(self) -> PickerArgInfo<'a> {
let value = self;
- let (long, alias) = match value.full.len() {
- 0 => (None, None),
- _ => {
- let long = Some(value.full[0]);
- let alias = if value.full.len() > 1 {
- Some(value.full[1..].to_vec())
- } else {
- None
- };
- (long, alias)
- }
+ let (long, alias) = if value.full.is_empty() {
+ (None, None)
+ } else {
+ let long = Some(value.full[0]);
+ let alias = if value.full.len() > 1 {
+ Some(value.full[1..].to_vec())
+ } else {
+ None
+ };
+ (long, alias)
};
PickerArgInfo {
@@ -169,7 +178,7 @@ where
Type: Pickable<'a>,
{
fn from(value: PickerArg<'a, Type>) -> Self {
- let mut result = Vec::new();
+ let mut result = Self::new();
let info = PickerArgInfo::from(value);
let possible_flags =
crate::parselib::build_possible_flags(ParserStyle::global_style(), &info);
@@ -231,81 +240,81 @@ impl PickerArgAttr {
/// Determines if the given `PickerArg` represents a positional parameter.
///
/// If the flag is positional (determined by `flag.is_positional()`), returns
- /// `PickerArgAttr::Positional`. Otherwise, invokes the `other` closure to
- /// produce and return a `PickerArgAttr`.
+ /// `Self::Positional`. Otherwise, invokes the `other` closure to
+ /// produce and return a `Self`.
///
/// # Parameters
///
/// - `flag`: A reference to the [`PickerArg`] to evaluate.
/// - `other`: A closure that returns a [`PickerArgAttr`] when the flag is
/// **not** positional.
- #[inline(always)]
- pub fn positional_or_else<'a, T>(
- flag: &PickerArg<'a, T>,
- other: fn() -> PickerArgAttr,
- ) -> PickerArgAttr
+ #[inline]
+ pub fn positional_or_else<'a, T>(flag: &PickerArg<'a, T>, other: fn() -> Self) -> Self
where
T: Pickable<'a>,
{
if flag.is_positional() {
- PickerArgAttr::Positional
+ Self::Positional
} else {
other()
}
}
/// Determines if the given `PickerArg` represents a positional parameter and returns
- /// `PickerArgAttr::Positional` if so. Otherwise, returns the provided `default` attribute.
+ /// `Self::Positional` if so. Otherwise, returns the provided `default` attribute.
///
/// # Parameters
///
/// - `flag`: A reference to the [`PickerArg`] to evaluate.
/// - `default`: The [`PickerArgAttr`] to return if the flag is not positional.
- #[inline(always)]
- pub fn positional_or<'a, T>(flag: &PickerArg<'a, T>, default: PickerArgAttr) -> PickerArgAttr
+ #[must_use]
+ #[inline]
+ pub const fn positional_or<'a, T>(flag: &PickerArg<'a, T>, default: Self) -> Self
where
T: Pickable<'a>,
{
if flag.is_positional() {
- PickerArgAttr::Positional
+ Self::Positional
} else {
default
}
}
/// Determines if the given `PickerArg` represents a positional parameter and returns
- /// `PickerArgAttr::Positional` if so. Otherwise, returns `PickerArgAttr::Single`.
+ /// `Self::Positional` if so. Otherwise, returns `Self::Single`.
///
/// # Parameters
///
/// - `flag`: A reference to the [`PickerArg`] to evaluate.
- #[inline(always)]
- pub fn positional_or_single<'a, T>(flag: &PickerArg<'a, T>) -> PickerArgAttr
+ #[must_use]
+ #[inline]
+ pub const fn positional_or_single<'a, T>(flag: &PickerArg<'a, T>) -> Self
where
T: Pickable<'a>,
{
if flag.is_positional() {
- PickerArgAttr::Positional
+ Self::Positional
} else {
- PickerArgAttr::Single
+ Self::Single
}
}
/// Determines if the given `PickerArg` represents a positional parameter and returns
- /// `PickerArgAttr::PositionalMulti` if so. Otherwise, returns `PickerArgAttr::Multi`.
+ /// `Self::PositionalMulti` if so. Otherwise, returns `Self::Multi`.
///
/// # Parameters
///
/// - `flag`: A reference to the [`PickerArg`] to evaluate.
- #[inline(always)]
- pub fn positional_or_multi<'a, T>(flag: &PickerArg<'a, T>) -> PickerArgAttr
+ #[must_use]
+ #[inline]
+ pub const fn positional_or_multi<'a, T>(flag: &PickerArg<'a, T>) -> Self
where
T: Pickable<'a>,
{
if flag.is_positional() {
- PickerArgAttr::PositionalMulti
+ Self::PositionalMulti
} else {
- PickerArgAttr::Multi
+ Self::Multi
}
}
}
diff --git a/arg_picker/src/builtin/pick_flag.rs b/arg_picker/src/builtin/pick_flag.rs
index b642a9a..8afc0fc 100644
--- a/arg_picker/src/builtin/pick_flag.rs
+++ b/arg_picker/src/builtin/pick_flag.rs
@@ -13,9 +13,9 @@ impl<'a> Pickable<'a> for Flag {
fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
if raw_strs.is_empty() {
- PickerArgResult::Parsed(Flag::Inactive)
+ PickerArgResult::Parsed(Self::Inactive)
} else {
- PickerArgResult::Parsed(Flag::Active)
+ PickerArgResult::Parsed(Self::Active)
}
}
}
diff --git a/arg_picker/src/builtin/pick_ip_attr.rs b/arg_picker/src/builtin/pick_ip_attr.rs
index d68fa15..57ac80e 100644
--- a/arg_picker/src/builtin/pick_ip_attr.rs
+++ b/arg_picker/src/builtin/pick_ip_attr.rs
@@ -4,36 +4,33 @@ use crate::SinglePickable;
impl SinglePickable for IpAddr {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<IpAddr>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
impl SinglePickable for Ipv4Addr {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<Ipv4Addr>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
impl SinglePickable for Ipv6Addr {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<Ipv6Addr>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
diff --git a/arg_picker/src/builtin/pick_numbers.rs b/arg_picker/src/builtin/pick_numbers.rs
index a5ab0a9..6cbd4fc 100644
--- a/arg_picker/src/builtin/pick_numbers.rs
+++ b/arg_picker/src/builtin/pick_numbers.rs
@@ -21,10 +21,7 @@ fn is_int_like(raw: &str) -> bool {
if bytes.is_empty() {
return false;
}
- let mut i = 0;
- if bytes[0] == b'-' || bytes[0] == b'+' {
- i = 1;
- }
+ let i = usize::from(bytes[0] == b'-' || bytes[0] == b'+');
if i >= bytes.len() {
return false;
}
@@ -69,12 +66,12 @@ impl_boundary_check_int! {
// Integer-like strings trigger a boundary.
impl BoundaryCheck for f32 {
fn check_boundary(raw: &str) -> bool {
- !is_float_like(raw) || raw.parse::<f32>().is_err()
+ !is_float_like(raw) || raw.parse::<Self>().is_err()
}
}
impl BoundaryCheck for f64 {
fn check_boundary(raw: &str) -> bool {
- !is_float_like(raw) || raw.parse::<f64>().is_err()
+ !is_float_like(raw) || raw.parse::<Self>().is_err()
}
}
diff --git a/arg_picker/src/builtin/pick_pathbuf.rs b/arg_picker/src/builtin/pick_pathbuf.rs
index 3bd4410..2b48e3d 100644
--- a/arg_picker/src/builtin/pick_pathbuf.rs
+++ b/arg_picker/src/builtin/pick_pathbuf.rs
@@ -7,12 +7,8 @@ use crate::{
impl SinglePickable for PathBuf {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(str) => match just_fmt::fmt_path_str(str) {
- Ok(formated) => Parsed(PathBuf::from(formated)),
- Err(_) => NotFound,
- },
- None => NotFound,
- }
+ str.map_or(NotFound, |str| {
+ just_fmt::fmt_path_str(str).map_or(NotFound, |formated| Parsed(Self::from(formated)))
+ })
}
}
diff --git a/arg_picker/src/builtin/pick_paths.rs b/arg_picker/src/builtin/pick_paths.rs
index 8e6c0fd..954464b 100644
--- a/arg_picker/src/builtin/pick_paths.rs
+++ b/arg_picker/src/builtin/pick_paths.rs
@@ -17,7 +17,7 @@ impl SinglePickable for FilePath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if path.exists() && path.is_file() {
- Parsed(FilePath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -33,7 +33,7 @@ impl SinglePickable for NoFilePath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if !path.exists() || !path.is_file() {
- Parsed(NoFilePath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -49,7 +49,7 @@ impl SinglePickable for DirPath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if path.exists() && path.is_dir() {
- Parsed(DirPath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -65,7 +65,7 @@ impl SinglePickable for NoDirPath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if !path.exists() || !path.is_dir() {
- Parsed(NoDirPath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -81,7 +81,7 @@ impl SinglePickable for SymlinkPath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if path.exists() && path.is_symlink() {
- Parsed(SymlinkPath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -97,7 +97,7 @@ impl SinglePickable for NoSymlinkPath {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
if !path.exists() || !path.is_symlink() {
- Parsed(NoSymlinkPath::from(path))
+ Parsed(Self::from(path))
} else {
NotFound
}
@@ -112,10 +112,10 @@ impl SinglePickable for NoPath {
fn pick_single(str: Option<&str>) -> PickerArgResult<Self> {
match <PathBuf as SinglePickable>::pick_single(str) {
Parsed(path) => {
- if !path.exists() {
- Parsed(NoPath::from(path))
- } else {
+ if path.exists() {
NotFound
+ } else {
+ Parsed(Self::from(path))
}
}
Unparsed => Unparsed,
@@ -132,7 +132,7 @@ impl SinglePickable for RecursiveFiles {
return NotFound;
}
if path.is_file() || path.is_symlink() {
- return Parsed(RecursiveFiles::from(vec![path]));
+ return Parsed(Self::from(vec![path]));
}
let mut entries = Vec::new();
if let Ok(dir_entries) = fs::read_dir(&path) {
@@ -145,7 +145,7 @@ impl SinglePickable for RecursiveFiles {
}
}
}
- Parsed(RecursiveFiles::from(entries))
+ Parsed(Self::from(entries))
}
Unparsed => Unparsed,
NotFound => NotFound,
diff --git a/arg_picker/src/builtin/pick_picker_args.rs b/arg_picker/src/builtin/pick_picker_args.rs
index 419cbc8..618960f 100644
--- a/arg_picker/src/builtin/pick_picker_args.rs
+++ b/arg_picker/src/builtin/pick_picker_args.rs
@@ -15,7 +15,7 @@ impl<'a> Pickable<'a> for PickerArgs<'a> {
}
fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
- let remains: Vec<String> = raw_strs.iter().map(|s| s.to_string()).collect();
+ let remains: Vec<String> = raw_strs.iter().map(ToString::to_string).collect();
Parsed(PickerArgs::Owned(remains))
}
}
diff --git a/arg_picker/src/builtin/pick_socket_attr.rs b/arg_picker/src/builtin/pick_socket_attr.rs
index 0c0dd71..ba9a410 100644
--- a/arg_picker/src/builtin/pick_socket_attr.rs
+++ b/arg_picker/src/builtin/pick_socket_attr.rs
@@ -4,36 +4,33 @@ use crate::SinglePickable;
impl SinglePickable for SocketAddr {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<SocketAddr>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
impl SinglePickable for SocketAddrV4 {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<SocketAddrV4>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
impl SinglePickable for SocketAddrV6 {
fn pick_single(str: Option<&str>) -> crate::PickerArgResult<Self> {
- match str {
- Some(s) => match s.parse::<SocketAddrV6>() {
- Ok(addr) => crate::PickerArgResult::Parsed(addr),
- Err(_) => crate::PickerArgResult::NotFound,
- },
- None => crate::PickerArgResult::NotFound,
- }
+ str.map_or(crate::PickerArgResult::NotFound, |s| {
+ s.parse::<Self>()
+ .map_or(crate::PickerArgResult::NotFound, |addr| {
+ crate::PickerArgResult::Parsed(addr)
+ })
+ })
}
}
diff --git a/arg_picker/src/builtin/pick_string.rs b/arg_picker/src/builtin/pick_string.rs
index c96f667..c7bdd4a 100644
--- a/arg_picker/src/builtin/pick_string.rs
+++ b/arg_picker/src/builtin/pick_string.rs
@@ -3,9 +3,6 @@ use crate::{SinglePickable, pickable_needed::*};
impl SinglePickable for String {
fn pick_single(str: Option<&str>) -> PickerArgResult<Self> {
- match str {
- Some(str) => PickerArgResult::Parsed(str.to_string()),
- None => NotFound,
- }
+ str.map_or(NotFound, |str| PickerArgResult::Parsed(str.to_string()))
}
}
diff --git a/arg_picker/src/infos.rs b/arg_picker/src/infos.rs
index c17b6a2..08b2be7 100644
--- a/arg_picker/src/infos.rs
+++ b/arg_picker/src/infos.rs
@@ -3,9 +3,9 @@ use crate::{Pickable, PickerArg, parselib::ParserStyle};
/// Represents the result of parsing or looking up a value.
///
/// This enum is generic over the type being parsed. It models three possible outcomes:
-/// - [`Unparsed`](PickerArgResult::Unparsed): The value has not yet been parsed (default).
-/// - [`Parsed`](PickerArgResult::Parsed): The value was successfully parsed into `Type`.
-/// - [`NotFound`](PickerArgResult::NotFound): The requested value could not be found.
+/// - [`Unparsed`](Self::Unparsed): The value has not yet been parsed (default).
+/// - [`Parsed`](Self::Parsed): The value was successfully parsed into `Type`.
+/// - [`NotFound`](Self::NotFound): The requested value could not be found.
#[derive(Default)]
pub enum PickerArgResult<Type> {
/// The value has not yet been parsed (default).
@@ -22,31 +22,25 @@ pub enum PickerArgResult<Type> {
impl<Type, E> From<Result<Type, E>> for PickerArgResult<Type> {
/// Converts a `Result<Type, E>` into a `PickerArgResult<Type>`.
///
- /// - `Ok(value)` maps to [`Parsed(value)`](PickerArgResult::Parsed).
- /// - `Err(_)` maps to [`NotFound`](PickerArgResult::NotFound).
+ /// - `Ok(value)` maps to [`Parsed(value)`](Self::Parsed).
+ /// - `Err(_)` maps to [`NotFound`](Self::NotFound).
fn from(result: Result<Type, E>) -> Self {
- match result {
- Ok(value) => PickerArgResult::Parsed(value),
- Err(_) => PickerArgResult::NotFound,
- }
+ result.map_or_else(|_| Self::NotFound, |value| Self::Parsed(value))
}
}
impl<Type> From<Option<Type>> for PickerArgResult<Type> {
/// Converts an `Option<Type>` into a `PickerArgResult<Type>`.
///
- /// - `Some(value)` maps to [`Parsed(value)`](PickerArgResult::Parsed).
- /// - `None` maps to [`NotFound`](PickerArgResult::NotFound).
+ /// - `Some(value)` maps to [`Parsed(value)`](Self::Parsed).
+ /// - `None` maps to [`NotFound`](Self::NotFound).
fn from(option: Option<Type>) -> Self {
- match option {
- Some(value) => PickerArgResult::Parsed(value),
- None => PickerArgResult::NotFound,
- }
+ option.map_or_else(|| Self::NotFound, |value| Self::Parsed(value))
}
}
impl<Type> PickerArgResult<Type> {
- /// Returns `true` if the result is [`Parsed`](PickerArgResult::Parsed).
+ /// Returns `true` if the result is [`Parsed`](Self::Parsed).
///
/// # Examples
///
@@ -59,11 +53,11 @@ impl<Type> PickerArgResult<Type> {
/// let result: PickerArgResult<i32> = PickerArgResult::NotFound;
/// assert!(!result.is_parsed());
/// ```
- pub fn is_parsed(&self) -> bool {
- matches!(self, PickerArgResult::Parsed(_))
+ pub const fn is_parsed(&self) -> bool {
+ matches!(self, Self::Parsed(_))
}
- /// Returns `true` if the result is [`Parsed`](PickerArgResult::Parsed) or [`NotFound`](PickerArgResult::NotFound).
+ /// Returns `true` if the result is [`Parsed`](Self::Parsed) or [`NotFound`](Self::NotFound).
/// i.e., the value exists (was either found or not yet parsed).
/// Typically indicates the value was "found" in some sense.
///
@@ -78,11 +72,11 @@ impl<Type> PickerArgResult<Type> {
/// let result: PickerArgResult<i32> = PickerArgResult::NotFound;
/// assert!(result.is_found());
/// ```
- pub fn is_found(&self) -> bool {
- matches!(self, PickerArgResult::Parsed(_) | PickerArgResult::NotFound)
+ pub const fn is_found(&self) -> bool {
+ matches!(self, Self::Parsed(_) | Self::NotFound)
}
- /// Returns `true` if the result is [`Unparsed`](PickerArgResult::Unparsed) or [`NotFound`](PickerArgResult::NotFound).
+ /// Returns `true` if the result is [`Unparsed`](Self::Unparsed) or [`NotFound`](Self::NotFound).
///
/// # Examples
///
@@ -95,11 +89,11 @@ impl<Type> PickerArgResult<Type> {
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(10);
/// assert!(!result.is_err());
/// ```
- pub fn is_err(&self) -> bool {
- !matches!(self, PickerArgResult::Parsed(_))
+ pub const fn is_err(&self) -> bool {
+ !matches!(self, Self::Parsed(_))
}
- /// Returns `Some(&Type)` if [`Parsed`](PickerArgResult::Parsed), otherwise `None`.
+ /// Returns `Some(&Type)` if [`Parsed`](Self::Parsed), otherwise `None`.
///
/// # Examples
///
@@ -112,18 +106,18 @@ impl<Type> PickerArgResult<Type> {
/// let result: PickerArgResult<i32> = PickerArgResult::NotFound;
/// assert_eq!(result.parsed(), None);
/// ```
- pub fn parsed(&self) -> Option<&Type> {
- if let PickerArgResult::Parsed(value) = self {
+ pub const fn parsed(&self) -> Option<&Type> {
+ if let Self::Parsed(value) = self {
Some(value)
} else {
None
}
}
- /// Returns the contained [`Parsed`](PickerArgResult::Parsed) value or panics with a given message.
+ /// Returns the contained [`Parsed`](Self::Parsed) value or panics with a given message.
///
/// # Panics
- /// Panics if the value is not [`Parsed`](PickerArgResult::Parsed), with a message including the provided `msg`.
+ /// Panics if the value is not [`Parsed`](Self::Parsed), with a message including the provided `msg`.
///
/// # Examples
///
@@ -135,15 +129,15 @@ impl<Type> PickerArgResult<Type> {
/// ```
pub fn expect(self, msg: &str) -> Type {
match self {
- PickerArgResult::Parsed(value) => value,
+ Self::Parsed(value) => value,
_ => panic!("{}", msg),
}
}
- /// Returns the contained [`Parsed`](PickerArgResult::Parsed) value or panics.
+ /// Returns the contained [`Parsed`](Self::Parsed) value or panics.
///
/// # Panics
- /// Panics if the value is not [`Parsed`](PickerArgResult::Parsed).
+ /// Panics if the value is not [`Parsed`](Self::Parsed).
///
/// # Examples
///
@@ -162,17 +156,17 @@ impl<Type> PickerArgResult<Type> {
/// ```
pub fn unwrap(self) -> Type {
match self {
- PickerArgResult::Parsed(value) => value,
- PickerArgResult::Unparsed => {
+ Self::Parsed(value) => value,
+ Self::Unparsed => {
panic!("called `PickerArgResult::unwrap()` on an `Unparsed` value")
}
- PickerArgResult::NotFound => {
+ Self::NotFound => {
panic!("called `PickerArgResult::unwrap()` on a `NotFound` value")
}
}
}
- /// Returns the contained [`Parsed`](PickerArgResult::Parsed) value or a provided `default`.
+ /// Returns the contained [`Parsed`](Self::Parsed) value or a provided `default`.
///
/// # Examples
///
@@ -187,12 +181,12 @@ impl<Type> PickerArgResult<Type> {
/// ```
pub fn unwrap_or(self, default: Type) -> Type {
match self {
- PickerArgResult::Parsed(value) => value,
+ Self::Parsed(value) => value,
_ => default,
}
}
- /// Returns the contained [`Parsed`](PickerArgResult::Parsed) value or computes it from a closure.
+ /// Returns the contained [`Parsed`](Self::Parsed) value or computes it from a closure.
///
/// # Examples
///
@@ -207,12 +201,12 @@ impl<Type> PickerArgResult<Type> {
/// ```
pub fn unwrap_or_else<F: FnOnce() -> Type>(self, f: F) -> Type {
match self {
- PickerArgResult::Parsed(value) => value,
+ Self::Parsed(value) => value,
_ => f(),
}
}
- /// Returns the contained [`Parsed`](PickerArgResult::Parsed) value or the default value of `Type`.
+ /// Returns the contained [`Parsed`](Self::Parsed) value or the default value of `Type`.
///
/// # Examples
///
@@ -230,14 +224,14 @@ impl<Type> PickerArgResult<Type> {
Type: Default,
{
match self {
- PickerArgResult::Parsed(value) => value,
+ Self::Parsed(value) => value,
_ => Type::default(),
}
}
/// Converts `PickerArgResult<Type>` into `Option<Type>`.
///
- /// Returns `Some(Type)` if [`Parsed`](PickerArgResult::Parsed), otherwise `None`.
+ /// Returns `Some(Type)` if [`Parsed`](Self::Parsed), otherwise `None`.
///
/// # Examples
///
@@ -255,12 +249,14 @@ impl<Type> PickerArgResult<Type> {
/// ```
pub fn to_option(self) -> Option<Type> {
match self {
- PickerArgResult::Parsed(value) => Some(value),
+ Self::Parsed(value) => Some(value),
_ => None,
}
}
}
+// In PickerArgInfo, positional, optional, multi, and is_flag may coexist.
+#[allow(clippy::struct_excessive_bools)]
/// Represents metadata about a command-line argument or flag.
///
/// This struct stores all relevant information about a tag/argument that can be used
@@ -294,17 +290,16 @@ where
impl<'a, T: Pickable<'a>> From<&'a PickerArg<'a, T>> for PickerArgInfo<'a> {
fn from(value: &'a PickerArg<'a, T>) -> Self {
- let (long, alias) = match value.full.len() {
- 0 => (None, None),
- _ => {
- let long = Some(value.full[0]);
- let alias = if value.full.len() > 1 {
- Some(value.full[1..].to_vec())
- } else {
- None
- };
- (long, alias)
- }
+ let (long, alias) = if value.full.is_empty() {
+ (None, None)
+ } else {
+ let long = Some(value.full[0]);
+ let alias = if value.full.len() > 1 {
+ Some(value.full[1..].to_vec())
+ } else {
+ None
+ };
+ (long, alias)
};
Self {
@@ -321,7 +316,8 @@ impl<'a, T: Pickable<'a>> From<&'a PickerArg<'a, T>> for PickerArgInfo<'a> {
impl<'a> PickerArgInfo<'a> {
/// Create a new `PickerTag` with default values.
- pub fn new() -> Self {
+ #[must_use]
+ pub const fn new() -> Self {
Self {
short: None,
long: None,
@@ -334,55 +330,62 @@ impl<'a> PickerArgInfo<'a> {
}
/// Set the short flag (e.g., `'n'` for `-n`).
- pub fn with_short(mut self, short: char) -> Self {
+ #[must_use]
+ pub const fn with_short(mut self, short: char) -> Self {
self.short = Some(short);
self
}
/// Set the long flag (e.g., `"name"` for `--name`).
- pub fn with_long(mut self, long: &'a str) -> Self {
+ #[must_use]
+ pub const fn with_long(mut self, long: &'a str) -> Self {
self.long = Some(long);
self
}
/// Set aliases for the tag.
+ #[must_use]
pub fn with_alias(mut self, alias: Vec<&'a str>) -> Self {
self.alias = Some(alias);
self
}
/// Mark the tag as positional.
- pub fn with_positional(mut self, positional: bool) -> Self {
+ #[must_use]
+ pub const fn with_positional(mut self, positional: bool) -> Self {
self.positional = positional;
self
}
/// Mark the tag as optional.
- pub fn with_optional(mut self, optional: bool) -> Self {
+ #[must_use]
+ pub const fn with_optional(mut self, optional: bool) -> Self {
self.optional = optional;
self
}
/// Mark the tag as multi-value.
- pub fn with_multi(mut self, multi: bool) -> Self {
+ #[must_use]
+ pub const fn with_multi(mut self, multi: bool) -> Self {
self.multi = multi;
self
}
/// Mark the tag as a flag that participates in parsing after `--`.
- pub fn with_is_flag(mut self, is_flag: bool) -> Self {
+ #[must_use]
+ pub const fn with_is_flag(mut self, is_flag: bool) -> Self {
self.is_flag = is_flag;
self
}
/// Set the short flag (e.g., `'n'` for `-n`).
- pub fn set_short(&mut self, short: char) -> &mut Self {
+ pub const fn set_short(&mut self, short: char) -> &mut Self {
self.short = Some(short);
self
}
/// Set the long flag (e.g., `"name"` for `--name`).
- pub fn set_long(&mut self, long: &'a str) -> &mut Self {
+ pub const fn set_long(&mut self, long: &'a str) -> &mut Self {
self.long = Some(long);
self
}
@@ -394,25 +397,25 @@ impl<'a> PickerArgInfo<'a> {
}
/// Set whether this tag is positional.
- pub fn set_positional(&mut self, positional: bool) -> &mut Self {
+ pub const fn set_positional(&mut self, positional: bool) -> &mut Self {
self.positional = positional;
self
}
/// Set whether this tag is optional.
- pub fn set_optional(&mut self, optional: bool) -> &mut Self {
+ pub const fn set_optional(&mut self, optional: bool) -> &mut Self {
self.optional = optional;
self
}
/// Set whether this tag accepts multiple values.
- pub fn set_multi(&mut self, multi: bool) -> &mut Self {
+ pub const fn set_multi(&mut self, multi: bool) -> &mut Self {
self.multi = multi;
self
}
/// Set whether this tag participates in parsing after a `--` separator.
- pub fn set_is_flag(&mut self, is_flag: bool) -> &mut Self {
+ pub const fn set_is_flag(&mut self, is_flag: bool) -> &mut Self {
self.is_flag = is_flag;
self
}
@@ -437,6 +440,7 @@ impl<'a> PickerArgInfo<'a> {
/// let info = PickerArgInfo::new();
/// assert_eq!(info.short_flag(), None);
/// ```
+ #[must_use]
pub fn short_flag(&self) -> Option<String> {
let short = self.short?;
Some(ParserStyle::global_style().flag_string(short))
@@ -462,13 +466,14 @@ impl<'a> PickerArgInfo<'a> {
/// let info = PickerArgInfo::new();
/// assert_eq!(info.long_flag(), None);
/// ```
+ #[must_use]
pub fn long_flag(&self) -> Option<String> {
let long = self.long?;
Some(ParserStyle::global_style().flag_string(long))
}
}
-impl<'a> Default for PickerArgInfo<'a> {
+impl Default for PickerArgInfo<'_> {
fn default() -> Self {
Self::new()
}
diff --git a/arg_picker/src/lib.rs b/arg_picker/src/lib.rs
index d292826..06ae959 100644
--- a/arg_picker/src/lib.rs
+++ b/arg_picker/src/lib.rs
@@ -1,5 +1,9 @@
#![doc = include_str!("../README.md")]
#![deny(missing_docs)]
+#![deny(clippy::pedantic)]
+#![deny(clippy::nursery)]
+// Some code requires wildcard imports to reduce boilerplate code
+#![allow(clippy::wildcard_imports)]
mod builtin;
diff --git a/arg_picker/src/parselib.rs b/arg_picker/src/parselib.rs
index 0fcd583..edb03bb 100644
--- a/arg_picker/src/parselib.rs
+++ b/arg_picker/src/parselib.rs
@@ -58,14 +58,16 @@ pub trait Matcher {
/// Convenience method that builds masked arguments from `PickerArgs` and a mask,
/// then calls `on_match_one`.
- fn match_one<'a>(ctx: MatcherContext<'a>) -> Option<usize> {
+ #[must_use]
+ fn match_one(ctx: MatcherContext<'_>) -> Option<usize> {
let masked_args = build_masked_args(ctx.args, ctx.mask);
Self::on_match_one(masked_args.as_slice(), ctx.style, ctx.arg_info)
}
/// Convenience method that builds masked arguments from `PickerArgs` and a mask,
/// then calls `on_match_all`.
- fn match_all<'a>(ctx: MatcherContext<'a>) -> Vec<usize> {
+ #[must_use]
+ fn match_all(ctx: MatcherContext<'_>) -> Vec<usize> {
let masked_args = build_masked_args(ctx.args, ctx.mask);
Self::on_match_all(masked_args.as_slice(), ctx.style, ctx.arg_info)
}
@@ -90,7 +92,7 @@ pub struct MatcherContext<'a> {
/// Metadata about the command-line argument/flag being processed.
///
/// Contains information such as short form (`-n`), long form (`--name`),
- /// aliases, and parsing flags (positional, optional, multi, is_flag).
+ /// aliases, and parsing flags (positional, optional, multi, `is_flag`).
/// Used by matchers to make decisions based on argument characteristics.
pub arg_info: &'a PickerArgInfo<'a>,
}
@@ -126,7 +128,8 @@ impl<'a> From<crate::TagPhaseContext<'a>> for MatcherContext<'a> {
///
/// * `mask` - A byte slice where non-zero values indicate claimed arguments.
/// * `idx` - The index to check in the mask.
-#[inline(always)]
+#[inline]
+#[must_use]
pub fn is_masked(mask: &[u8], idx: usize) -> bool {
idx < mask.len() && mask[idx] != 0
}
@@ -141,7 +144,8 @@ pub fn is_masked(mask: &[u8], idx: usize) -> bool {
///
/// * `args` - The full set of parsed arguments.
/// * `mask` - A byte slice where `0` means available and non-zero means already claimed.
-#[inline(always)]
+#[inline]
+#[must_use]
pub fn build_masked_args<'a>(args: &'a PickerArgs, mask: &'a [u8]) -> Vec<MaskedArg<'a>> {
let mut cidx = 0;
args.iter()
@@ -150,13 +154,13 @@ pub fn build_masked_args<'a>(args: &'a PickerArgs, mask: &'a [u8]) -> Vec<Masked
cidx += 1;
// Include args where mask is 0 (available/not yet claimed).
// mask[i] = 0 means available; mask[i] != 0 means already claimed.
- if !is_masked(mask, idx) {
+ if is_masked(mask, idx) {
+ None
+ } else {
Some(MaskedArg {
raw: r,
raw_idx: idx,
})
- } else {
- None
}
})
.collect()
diff --git a/arg_picker/src/parselib/arg_matcher.rs b/arg_picker/src/parselib/arg_matcher.rs
index 38bb9cc..d26f6fb 100644
--- a/arg_picker/src/parselib/arg_matcher.rs
+++ b/arg_picker/src/parselib/arg_matcher.rs
@@ -29,7 +29,7 @@ pub struct ArgMatcher;
impl ArgMatcher {
/// Check whether `raw` matches `flag_str`, optionally with an inline value
/// separated by the style's value separator (`=` for Unix, `:` for PowerShell).
- #[inline(always)]
+ #[inline]
fn matches(raw: &str, flag_str: &str, case_sensitive: bool, sep: char) -> bool {
let eq_match =
|r: &str, f: &str| r.len() > f.len() && r.as_bytes().get(f.len()) == Some(&(sep as u8));
@@ -46,7 +46,7 @@ impl ArgMatcher {
/// Check whether the argument contains its value inline via the style's
/// value separator (eq mode), so no extra mask slot is needed.
- #[inline(always)]
+ #[inline]
fn is_inline_value(raw: &str, flag_str: &str, sep: char) -> bool {
raw.len() > flag_str.len() && raw.as_bytes().get(flag_str.len()) == Some(&(sep as u8))
}
diff --git a/arg_picker/src/parselib/flag_matcher.rs b/arg_picker/src/parselib/flag_matcher.rs
index e93d35a..2484cc9 100644
--- a/arg_picker/src/parselib/flag_matcher.rs
+++ b/arg_picker/src/parselib/flag_matcher.rs
@@ -18,7 +18,7 @@ impl Matcher for FlagMatcher {
arg_info: &PickerArgInfo,
) -> Option<usize> {
let possible_flags = build_possible_flags(style, arg_info);
- let flag_refs: Vec<&str> = possible_flags.iter().map(|s| s.as_str()).collect();
+ let flag_refs: Vec<&str> = possible_flags.iter().map(String::as_str).collect();
let end_of_options = seek_end_of_options(args, style);
let result = get_seeked_first(multi_seek_eq(args, &flag_refs, style.case_sensitive));
@@ -45,7 +45,7 @@ fn single_pass_match_all(
style: &ParserStyle,
possible_flags: &[String],
) -> Vec<usize> {
- let flag_refs: Vec<&str> = possible_flags.iter().map(|s| s.as_str()).collect();
+ let flag_refs: Vec<&str> = possible_flags.iter().map(String::as_str).collect();
let eoo = style.end_of_options;
let case_sensitive = style.case_sensitive;
@@ -67,12 +67,12 @@ fn single_pass_match_all(
// Only match flags before the end-of-options marker.
if end_pos.is_none() {
- let matched = if case_sensitive {
+ let is_matched = if case_sensitive {
flag_refs.contains(&arg.raw)
} else {
flag_refs.iter().any(|s| arg.raw.eq_ignore_ascii_case(s))
};
- if matched {
+ if is_matched {
matches.push(arg.raw_idx);
}
}
diff --git a/arg_picker/src/parselib/multi_arg_matcher.rs b/arg_picker/src/parselib/multi_arg_matcher.rs
index 748b1be..6791121 100644
--- a/arg_picker/src/parselib/multi_arg_matcher.rs
+++ b/arg_picker/src/parselib/multi_arg_matcher.rs
@@ -115,7 +115,7 @@ impl Matcher for MultiArgMatcher {
}
impl MultiArgMatcher {
- #[inline(always)]
+ #[inline]
fn flag_match(raw: &str, flag_str: &str, case_sensitive: bool, sep: char) -> bool {
let eq =
|r: &str, f: &str| r.len() > f.len() && r.as_bytes().get(f.len()) == Some(&(sep as u8));
@@ -130,7 +130,7 @@ impl MultiArgMatcher {
}
}
- #[inline(always)]
+ #[inline]
fn is_eq_match(raw: &str, flags: &[String], case_sensitive: bool, sep: char) -> bool {
flags.iter().any(|f| {
Self::flag_match(raw, f, case_sensitive, sep)
diff --git a/arg_picker/src/parselib/pos_matcher.rs b/arg_picker/src/parselib/pos_matcher.rs
index 279e01e..96aceb3 100644
--- a/arg_picker/src/parselib/pos_matcher.rs
+++ b/arg_picker/src/parselib/pos_matcher.rs
@@ -14,7 +14,7 @@ pub struct PositionalMatcher;
impl PositionalMatcher {
/// Check whether `raw` looks like a named flag (starts with a prefix).
- #[inline(always)]
+ #[inline]
fn is_flag_like(raw: &str, style: &ParserStyle) -> bool {
raw.starts_with(style.long_prefix) || raw.starts_with(style.short_prefix)
}
diff --git a/arg_picker/src/parselib/single_matcher.rs b/arg_picker/src/parselib/single_matcher.rs
index 25c4741..d7cf6a4 100644
--- a/arg_picker/src/parselib/single_matcher.rs
+++ b/arg_picker/src/parselib/single_matcher.rs
@@ -18,12 +18,11 @@ impl SingleMatcher {
/// For named args, only complete pairs (flag + value) are kept.
/// Flag occurrences without a following value or inline separator
/// are dropped so they remain available for other matchers.
- #[inline(always)]
+ #[inline]
+ #[must_use]
pub fn tag(ctx: TagPhaseContext) -> Vec<usize> {
if ctx.arg_info.positional {
- PositionalMatcher::match_one(ctx.into())
- .map(|i| vec![i])
- .unwrap_or_default()
+ PositionalMatcher::match_one(ctx.into()).map_or_else(Vec::new, |i| vec![i])
} else {
let args = ctx.args;
let positions = ArgMatcher::match_all(ctx.into());
diff --git a/arg_picker/src/parselib/style.rs b/arg_picker/src/parselib/style.rs
index 36ba8f0..81dfe72 100644
--- a/arg_picker/src/parselib/style.rs
+++ b/arg_picker/src/parselib/style.rs
@@ -56,7 +56,7 @@ impl<'a> ParserStyle<'a> {
///
/// A `String` with the prefix and the flag name combined.
#[must_use]
- #[inline(always)]
+ #[inline]
pub fn flag_string<F>(&self, flag: F) -> String
where
F: Into<FlagStr<'a>>,
@@ -88,7 +88,7 @@ pub enum FlagStr<'a> {
Long(&'a str),
}
-impl<'a> From<char> for FlagStr<'a> {
+impl From<char> for FlagStr<'_> {
/// Converts a single character into a `FlagStr::Short`.
fn from(c: char) -> Self {
FlagStr::Short(c)
@@ -129,36 +129,36 @@ impl<'a> From<&'a String> for FlagStr<'a> {
#[repr(u8)]
#[derive(Default, Clone, Copy, PartialEq, Eq)]
pub enum ParserStyleNamingCase {
- /// snake_case format: words are separated by underscores, all lowercase.
+ /// `snake_case` format: words are separated by underscores, all lowercase.
///
/// Example: `brew_coffee`
#[default]
Snake,
- /// camelCase format: first word is lowercase, subsequent words are capitalized.
+ /// `camelCase` format: first word is lowercase, subsequent words are capitalized.
///
/// Example: `brewCoffee`
Camel,
- /// PascalCase format: every word starts with an uppercase letter.
+ /// `PascalCase` format: every word starts with an uppercase letter.
///
/// Example: `BrewCoffee`
Pascal,
- /// kebab-case format: words are separated by hyphens, all lowercase.
+ /// `kebab-case` format: words are separated by hyphens, all lowercase.
///
/// Example: `brew-coffee`
Kebab,
- /// dot.case format: words are separated by dots, all lowercase.
+ /// `dot.case` format: words are separated by dots, all lowercase.
///
/// Example: `brew.coffee`
Dot,
- /// Title Case format: words are separated by spaces, each word capitalized.
+ /// `Title Case` format: words are separated by spaces, each word capitalized.
///
/// Example: `Brew Coffee`
Title,
- /// lower case format: words are separated by spaces, all lowercase.
+ /// `lower case` format: words are separated by spaces, all lowercase.
///
/// Example: `brew coffee`
Lower,
- /// UPPER CASE format: words are separated by spaces, all uppercase.
+ /// `UPPER CASE` format: words are separated by spaces, all uppercase.
///
/// Example: `BREW COFFEE`
Upper,
@@ -187,14 +187,14 @@ impl ParserStyleNamingCase {
S: Into<String> + From<String>,
{
match self {
- ParserStyleNamingCase::Camel => just_fmt::camel_case!(s.into()).into(),
- ParserStyleNamingCase::Pascal => just_fmt::pascal_case!(s.into()).into(),
- ParserStyleNamingCase::Kebab => just_fmt::kebab_case!(s.into()).into(),
- ParserStyleNamingCase::Snake => just_fmt::snake_case!(s.into()).into(),
- ParserStyleNamingCase::Dot => just_fmt::dot_case!(s.into()).into(),
- ParserStyleNamingCase::Title => just_fmt::title_case!(s.into()).into(),
- ParserStyleNamingCase::Lower => just_fmt::lower_case!(s.into()).into(),
- ParserStyleNamingCase::Upper => just_fmt::upper_case!(s.into()).into(),
+ Self::Camel => just_fmt::camel_case!(s.into()).into(),
+ Self::Pascal => just_fmt::pascal_case!(s.into()).into(),
+ Self::Kebab => just_fmt::kebab_case!(s.into()).into(),
+ Self::Snake => just_fmt::snake_case!(s.into()).into(),
+ Self::Dot => just_fmt::dot_case!(s.into()).into(),
+ Self::Title => just_fmt::title_case!(s.into()).into(),
+ Self::Lower => just_fmt::lower_case!(s.into()).into(),
+ Self::Upper => just_fmt::upper_case!(s.into()).into(),
}
}
}
@@ -238,7 +238,7 @@ pub const WINDOWS_STYLE: ParserStyle = ParserStyle {
static GLOBAL_STYLE: OnceLock<ParserStyle<'static>> = OnceLock::new();
static GLOBAL_STYLE_SET: AtomicBool = AtomicBool::new(false);
-impl<'a> ParserStyle<'a> {
+impl ParserStyle<'_> {
/// Sets the global parser style.
///
/// This function can only be called once. Subsequent calls will have no effect.
diff --git a/arg_picker/src/parselib/utils.rs b/arg_picker/src/parselib/utils.rs
index 47c5b55..dc4e091 100644
--- a/arg_picker/src/parselib/utils.rs
+++ b/arg_picker/src/parselib/utils.rs
@@ -8,7 +8,7 @@ use crate::{
/// This function generates formatted flag strings (e.g., `-h`, `--help`) from the short flag,
/// long flag, and any aliases defined in the argument info. The long flag and alias names
/// are converted according to the style's naming case convention before being formatted.
-#[inline(always)]
+#[must_use]
pub fn build_possible_flags(style: &ParserStyle, arg_info: &PickerArgInfo) -> Vec<String> {
let mut possible_flags = vec![];
@@ -46,11 +46,7 @@ pub fn seek_single<'a>(raw_strs: &'a [&'a str]) -> Option<&'a str> {
1 => {
let s = raw_strs[0];
let sep = ParserStyle::global_style().value_separator;
- if let Some(pos) = s.rfind(sep) {
- Some(&s[pos + 1..])
- } else {
- Some(s)
- }
+ s.rfind(sep).map_or(Some(s), |pos| Some(&s[pos + 1..]))
}
_ => Some(raw_strs[1]),
}
@@ -79,7 +75,7 @@ pub fn seek_end_of_options(args: &[MaskedArg], style: &ParserStyle) -> Option<us
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn seek_eq(args: &[MaskedArg], string: &str, case_sensitive: bool) -> Vec<usize> {
args.iter()
.filter(|arg| {
@@ -97,7 +93,7 @@ pub fn seek_eq(args: &[MaskedArg], string: &str, case_sensitive: bool) -> Vec<us
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn seek_contains(args: &[MaskedArg], string: &str, case_sensitive: bool) -> Vec<usize> {
args.iter()
.filter(|arg| {
@@ -115,7 +111,7 @@ pub fn seek_contains(args: &[MaskedArg], string: &str, case_sensitive: bool) ->
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn seek_start_with(args: &[MaskedArg], string: &str, case_sensitive: bool) -> Vec<usize> {
args.iter()
.filter(|arg| {
@@ -133,7 +129,7 @@ pub fn seek_start_with(args: &[MaskedArg], string: &str, case_sensitive: bool) -
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn seek_end_with(args: &[MaskedArg], string: &str, case_sensitive: bool) -> Vec<usize> {
args.iter()
.filter(|arg| {
@@ -151,7 +147,7 @@ pub fn seek_end_with(args: &[MaskedArg], string: &str, case_sensitive: bool) ->
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn multi_seek_eq(args: &[MaskedArg], strings: &[&str], case_sensitive: bool) -> Vec<usize> {
args.iter()
.filter(|arg| {
@@ -169,7 +165,7 @@ pub fn multi_seek_eq(args: &[MaskedArg], strings: &[&str], case_sensitive: bool)
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn multi_seek_contains(
args: &[MaskedArg],
strings: &[&str],
@@ -194,7 +190,7 @@ pub fn multi_seek_contains(
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn multi_seek_start_with(
args: &[MaskedArg],
strings: &[&str],
@@ -219,7 +215,7 @@ pub fn multi_seek_start_with(
///
/// Returns the indices of matching arguments.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn multi_seek_end_with(
args: &[MaskedArg],
strings: &[&str],
@@ -245,10 +241,10 @@ pub fn multi_seek_end_with(
/// This is useful for converting owned `String` vectors into borrowed `&str` slices
/// for functions that take `&[&str]` or similar parameters.
#[must_use]
-#[inline(always)]
+#[inline]
#[doc(hidden)]
pub fn vec_string_to_vec_str(input: &[String]) -> Vec<&str> {
- input.iter().map(|s| s.as_str()).collect()
+ input.iter().map(String::as_str).collect()
}
/// Converts a `&Vec<String>` into a `Vec<&str>` by borrowing each string's slice.
@@ -270,7 +266,7 @@ macro_rules! vec_string_slice {
///
/// Returns `Some(index)` if the vector is non-empty, otherwise `None`.
#[must_use]
-#[inline(always)]
+#[inline]
pub fn get_seeked_first(seeked: Vec<usize>) -> Option<usize> {
seeked.into_iter().next()
}
diff --git a/arg_picker/src/pickable/multi_pickable.rs b/arg_picker/src/pickable/multi_pickable.rs
index 404c23b..c5cd810 100644
--- a/arg_picker/src/pickable/multi_pickable.rs
+++ b/arg_picker/src/pickable/multi_pickable.rs
@@ -35,7 +35,7 @@ pub trait MultiPickableWithBoundary: Sized {
pub struct NoBoundary;
impl BoundaryCheck for NoBoundary {
- #[inline(always)]
+ #[inline]
fn check_boundary(_raw: &str) -> bool {
false
}
@@ -46,7 +46,7 @@ impl<T: SinglePickable> MultiPickableWithBoundary for Vec<T> {
type Checker = NoBoundary;
fn pick_multi(raw: Vec<String>) -> PickerArgResult<Self> {
- let mut result = Vec::with_capacity(raw.len());
+ let mut result = Self::with_capacity(raw.len());
for s in &raw {
match T::pick_single(Some(s)) {
PickerArgResult::Parsed(v) => result.push(v),
@@ -87,6 +87,6 @@ where
fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
let strs = strip_flag(raw_strs);
let owned: Vec<String> = strs.iter().map(|&s| s.to_string()).collect();
- <Vec<T> as MultiPickableWithBoundary>::pick_multi(owned)
+ <Self as MultiPickableWithBoundary>::pick_multi(owned)
}
}
diff --git a/arg_picker/src/picker.rs b/arg_picker/src/picker.rs
index f722fb5..a7f0dfb 100644
--- a/arg_picker/src/picker.rs
+++ b/arg_picker/src/picker.rs
@@ -24,7 +24,8 @@ impl<'a> Picker<'a> {
/// 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).
- pub fn from_args() -> Picker<'a, ()> {
+ #[must_use]
+ pub fn from_args() -> Self {
Self::from_args_skip(1)
}
@@ -34,7 +35,8 @@ impl<'a> Picker<'a> {
/// 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.
- pub fn from_args_skip(skip: usize) -> Picker<'a, ()> {
+ #[must_use]
+ pub fn from_args_skip(skip: usize) -> Self {
let args = std::env::args().skip(skip).collect::<Vec<String>>();
Picker {
route_phantom: PhantomData,
@@ -48,6 +50,7 @@ impl<'a> Picker<'a> {
/// 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,
@@ -76,8 +79,8 @@ pub enum PickerArgs<'a> {
impl<'a> From<PickerArgs<'a>> for Vec<String> {
fn from(value: PickerArgs<'a>) -> Self {
match value {
- PickerArgs::Slice(items) => items.iter().map(|s| s.to_string()).collect(),
- PickerArgs::Vec(items) => items.into_iter().map(|s| s.to_string()).collect(),
+ 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,
}
}
@@ -88,12 +91,12 @@ impl<'a> From<&'a PickerArgs<'a>> for Vec<&'a str> {
match value {
PickerArgs::Slice(items) => items.to_vec(),
PickerArgs::Vec(items) => items.clone(),
- PickerArgs::Owned(items) => items.iter().map(|s| s.as_str()).collect(),
+ PickerArgs::Owned(items) => items.iter().map(String::as_str).collect(),
}
}
}
-impl<'a> Default for PickerArgs<'a> {
+impl Default for PickerArgs<'_> {
fn default() -> Self {
Self::Vec(vec![])
}
@@ -101,7 +104,8 @@ impl<'a> Default for PickerArgs<'a> {
impl<'a> PickerArgs<'a> {
/// Returns the number of arguments.
- pub fn len(&self) -> usize {
+ #[must_use]
+ pub const fn len(&self) -> usize {
match self {
PickerArgs::Slice(items) => items.len(),
PickerArgs::Vec(items) => items.len(),
@@ -110,11 +114,13 @@ impl<'a> PickerArgs<'a> {
}
/// Returns `true` if there are no arguments.
- pub fn is_empty(&self) -> bool {
+ #[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()),
@@ -124,16 +130,17 @@ impl<'a> PickerArgs<'a> {
}
/// 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(|s| s.as_str()),
+ PickerArgs::Owned(items) => items.get(index).map(String::as_str),
}
}
}
-impl<'a> Index<usize> for PickerArgs<'a> {
+impl Index<usize> for PickerArgs<'_> {
type Output = str;
fn index(&self, index: usize) -> &Self::Output {
@@ -185,7 +192,7 @@ impl<'a, Route> From<Vec<&'a str>> for Picker<'a, Route> {
}
}
-impl<'a, Route> From<Vec<String>> for Picker<'a, Route> {
+impl<Route> From<Vec<String>> for Picker<'_, Route> {
fn from(value: Vec<String>) -> Self {
Picker {
route_phantom: PhantomData,
@@ -196,37 +203,42 @@ impl<'a, Route> From<Vec<String>> for Picker<'a, Route> {
impl<'a, Route> Picker<'a, Route> {
/// Returns a reference to the internal `PickerArgs`.
- pub fn args(&self) -> &PickerArgs<'a> {
+ #[must_use]
+ pub const fn args(&self) -> &PickerArgs<'a> {
&self.args
}
/// Returns a mutable reference to the internal `PickerArgs`.
- pub fn args_mut(&mut self) -> &mut PickerArgs<'a> {
+ 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.
- pub fn len(&self) -> usize {
+ #[must_use]
+ pub const fn len(&self) -> usize {
self.args.len()
}
/// Returns `true` if there are no arguments.
- pub fn is_empty(&self) -> bool {
+ #[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<'a, Route> Index<usize> for Picker<'a, Route> {
+impl Index<usize> for Picker<'_> {
type Output = str;
fn index(&self, index: usize) -> &Self::Output {
@@ -234,7 +246,7 @@ impl<'a, Route> Index<usize> for Picker<'a, Route> {
}
}
-impl<'a, Route> Index<usize> for &Picker<'a, Route> {
+impl<'a, Route> Index<usize> for &'a Picker<'a, Route> {
type Output = str;
fn index(&self, index: usize) -> &Self::Output {
@@ -266,22 +278,20 @@ impl<'a> Iterator for PickerIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
match self {
- PickerIter::Slice(iter) => iter.next().copied(),
- PickerIter::Vec(iter) => iter.next().copied(),
- PickerIter::Owned(iter) => iter.next().map(|s| s.as_str()),
+ 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) => iter.size_hint(),
- PickerIter::Vec(iter) => iter.size_hint(),
+ PickerIter::Slice(iter) | PickerIter::Vec(iter) => iter.size_hint(),
PickerIter::Owned(iter) => iter.size_hint(),
}
}
}
-impl<'a> ExactSizeIterator for PickerIter<'a> {}
+impl ExactSizeIterator for PickerIter<'_> {}
impl<'a, Route> Picker<'a, Route> {
/// Creates a `PickerPattern1` from the given arg to start a picking chain.
@@ -473,7 +483,7 @@ impl<'a> IntoPicker<'a> for &'a [&'a str] {
impl<'a> IntoPicker<'a> for &'a [String] {
fn to_picker(self) -> Picker<'a, ()> {
- let vec: Vec<&str> = self.iter().map(|s| s.as_str()).collect();
+ let vec: Vec<&str> = self.iter().map(String::as_str).collect();
Picker {
route_phantom: PhantomData,
args: PickerArgs::Vec(vec),
@@ -492,7 +502,7 @@ impl<'a> IntoPicker<'a> for Vec<&'a str> {
impl<'a> IntoPicker<'a> for &'a Vec<String> {
fn to_picker(self) -> Picker<'a, ()> {
- let slice: Vec<&str> = self.iter().map(|s| s.as_str()).collect();
+ let slice: Vec<&str> = self.iter().map(String::as_str).collect();
Picker {
route_phantom: PhantomData,
args: PickerArgs::Vec(slice),
@@ -510,7 +520,7 @@ impl<'a> IntoPicker<'a> for Vec<String> {
}
impl<'a, Route> Picker<'a, Route> {
- /// Build the PickerPattern via Arguments
+ /// Build the `PickerPattern` via Arguments
pub fn build_pattern1<N>(
args: PickerArgs<'a>,
arg: &'a PickerArg<'a, N>,
diff --git a/arg_picker/src/picker/patterns.rs b/arg_picker/src/picker/patterns.rs
index 5806605..7058d47 100644
--- a/arg_picker/src/picker/patterns.rs
+++ b/arg_picker/src/picker/patterns.rs
@@ -33,8 +33,7 @@ internal_repeat!(1..=32 => {
#[allow(clippy::type_complexity)]
pub fn or<F>(mut self, func: F) -> Self
where
- F: FnMut() -> T$,
- F: 'static,
+ F: 'static + FnMut() -> T$,
{
self.default_$ = Some(Box::new(func));
self
@@ -65,8 +64,7 @@ internal_repeat!(1..=32 => {
///
pub fn or_route<F>(mut self, func: F) -> Self
where
- F: FnMut() -> Route,
- F: 'static,
+ F: 'static + FnMut() -> Route,
{
self.route_$ = Some(Box::new(func));
self
@@ -110,8 +108,7 @@ internal_repeat!(1..=32 => {
#[allow(clippy::type_complexity)]
pub fn post<F>(mut self, func: F) -> Self
where
- F: FnMut(T$) -> T$,
- F: 'static,
+ F: 'static + FnMut(T$) -> T$,
{
self.post_$ = Some(Box::new(func));
self
@@ -167,7 +164,6 @@ internal_repeat!(1..32 => {
where
N: Pickable<'a>,
F: FnMut() -> N + 'static,
- F: 'static,
{
self.pick(arg).or(func)
}
@@ -197,7 +193,6 @@ internal_repeat!(1..32 => {
where
N: Pickable<'a>,
F: FnMut() -> Route + 'static,
- F: 'static,
{
self.pick(arg).or_route(func)
}
diff --git a/arg_picker/src/value/flag.rs b/arg_picker/src/value/flag.rs
index c0673bd..6449d65 100644
--- a/arg_picker/src/value/flag.rs
+++ b/arg_picker/src/value/flag.rs
@@ -80,9 +80,9 @@ impl Flag {
/// [`Active`]: Flag::Active
/// [`Inactive`]: Flag::Inactive
#[must_use]
- #[inline(always)]
+ #[inline]
pub fn bool(&self) -> bool {
- *self == Flag::Active
+ *self == Self::Active
}
}
@@ -101,7 +101,7 @@ impl PartialEq<Flag> for bool {
impl From<bool> for Flag {
fn from(value: bool) -> Self {
- if value { Flag::Active } else { Flag::Inactive }
+ if value { Self::Active } else { Self::Inactive }
}
}
@@ -127,19 +127,19 @@ impl Deref for Flag {
fn deref(&self) -> &bool {
match self {
- Flag::Active => &true,
- Flag::Inactive => &false,
+ Self::Active => &true,
+ Self::Inactive => &false,
}
}
}
impl Not for Flag {
- type Output = Flag;
+ type Output = Self;
- fn not(self) -> Flag {
+ fn not(self) -> Self {
match self {
- Flag::Active => Flag::Inactive,
- Flag::Inactive => Flag::Active,
+ Self::Active => Self::Inactive,
+ Self::Inactive => Self::Active,
}
}
}
diff --git a/arg_picker/src/value/paths.rs b/arg_picker/src/value/paths.rs
index 403d6cc..d64a09f 100644
--- a/arg_picker/src/value/paths.rs
+++ b/arg_picker/src/value/paths.rs
@@ -117,7 +117,7 @@ pub struct NoPath {
path: PathBuf,
}
-/// Implements common trait impls (From, AsRef, Deref, DerefMut) for a path wrapper type.
+/// Implements common trait impls (`From`, `AsRef`, `Deref`, `DerefMut`) for a path wrapper type.
macro_rules! impl_path_traits {
($type:ident) => {
impl From<PathBuf> for $type {
@@ -227,12 +227,14 @@ impl DerefMut for RecursiveFiles {
impl RecursiveFiles {
/// Returns the number of file paths.
- pub fn len(&self) -> usize {
+ #[must_use]
+ pub const fn len(&self) -> usize {
self.paths.len()
}
/// Returns `true` if there are no file paths.
- pub fn is_empty(&self) -> bool {
+ #[must_use]
+ pub const fn is_empty(&self) -> bool {
self.paths.is_empty()
}
@@ -242,8 +244,17 @@ impl RecursiveFiles {
}
}
-impl From<Vec<RecursiveFiles>> for RecursiveFiles {
- fn from(value: Vec<RecursiveFiles>) -> Self {
+impl<'a> IntoIterator for &'a RecursiveFiles {
+ type Item = &'a PathBuf;
+ type IntoIter = std::slice::Iter<'a, PathBuf>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl From<Vec<Self>> for RecursiveFiles {
+ fn from(value: Vec<Self>) -> Self {
Self {
paths: value.into_iter().flat_map(|r| r.paths).collect(),
}
diff --git a/arg_picker/src/value/vec_until.rs b/arg_picker/src/value/vec_until.rs
index 04d87ce..6394cbf 100644
--- a/arg_picker/src/value/vec_until.rs
+++ b/arg_picker/src/value/vec_until.rs
@@ -22,6 +22,7 @@ pub struct VecUntil<T> {
impl<T> VecUntil<T> {
/// Consumes `self` and returns the underlying [`Vec<T>`].
+ #[must_use]
pub fn into_inner(self) -> Vec<T> {
self.inner
}
@@ -29,7 +30,7 @@ impl<T> VecUntil<T> {
impl<T> From<Vec<T>> for VecUntil<T> {
fn from(v: Vec<T>) -> Self {
- VecUntil {
+ Self {
inner: v,
_marker: PhantomData,
}
@@ -72,7 +73,7 @@ where
PickerArgResult::Unparsed => {}
}
}
- PickerArgResult::Parsed(VecUntil {
+ PickerArgResult::Parsed(Self {
inner,
_marker: PhantomData,
})
@@ -97,7 +98,7 @@ where
return positions;
}
- let start = if is_positional { 0 } else { 1 };
+ let start = usize::from(!is_positional);
if start >= positions.len() {
return positions;
}
@@ -118,7 +119,7 @@ where
fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
let strs = strip_flag(raw_strs);
let owned: Vec<String> = strs.iter().map(|&s| s.to_string()).collect();
- <VecUntil<T> as MultiPickableWithBoundary>::pick_multi(owned)
+ <Self as MultiPickableWithBoundary>::pick_multi(owned)
}
}