aboutsummaryrefslogtreecommitdiff
path: root/mingling/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'mingling/src/parser')
-rw-r--r--mingling/src/parser/args.rs40
-rw-r--r--mingling/src/parser/picker.rs60
-rw-r--r--mingling/src/parser/picker/bools.rs4
-rw-r--r--mingling/src/parser/picker/builtin.rs4
-rw-r--r--mingling/src/parser/picker/path.rs2
-rw-r--r--mingling/src/parser/picker/path/rule.rs12
6 files changed, 76 insertions, 46 deletions
diff --git a/mingling/src/parser/args.rs b/mingling/src/parser/args.rs
index 2dc0feb..23275c2 100644
--- a/mingling/src/parser/args.rs
+++ b/mingling/src/parser/args.rs
@@ -11,7 +11,10 @@ pub struct Argument {
impl From<Vec<&str>> for Argument {
fn from(vec: Vec<&str>) -> Self {
Argument {
- vec: vec.into_iter().map(|s| s.to_string()).collect(),
+ vec: vec
+ .into_iter()
+ .map(std::string::ToString::to_string)
+ .collect(),
}
}
}
@@ -85,18 +88,17 @@ impl Argument {
}
let flag: Flag = flag.into();
- if !flag.is_empty() {
- // Has any flag
- for argument in flag.iter() {
- let value = special_argument!(self.vec, argument);
- if value.is_some() {
- return value;
- }
- }
- } else {
+ if flag.is_empty() {
// No flag
return Some(self.vec.remove(0));
}
+ // Has any flag
+ for argument in flag.iter() {
+ let value = special_argument!(self.vec, argument);
+ if value.is_some() {
+ return value;
+ }
+ }
None
}
@@ -135,15 +137,7 @@ impl Argument {
}
let flag: Flag = flag.into();
- if !flag.is_empty() {
- // Has any flag
- for argument in flag.iter() {
- let enabled = special_flag!(self.vec, argument);
- if enabled {
- return enabled;
- }
- }
- } else {
+ if flag.is_empty() {
let first = self.vec.remove(0);
let first_lower = first.to_lowercase();
let trimmed = first_lower.trim();
@@ -154,6 +148,13 @@ impl Argument {
};
return result;
}
+ // Has any flag
+ for argument in flag.iter() {
+ let enabled = special_flag!(self.vec, argument);
+ if enabled {
+ return enabled;
+ }
+ }
false
}
@@ -167,6 +168,7 @@ impl Argument {
///
/// This method filters out all command-line style flags from the arguments,
/// returning a new `Argument` instance containing only non-flag arguments.
+ #[must_use]
pub fn strip_all_flags(mut self) -> Self {
self.vec.retain(|f| !f.starts_with('-'));
self
diff --git a/mingling/src/parser/picker.rs b/mingling/src/parser/picker.rs
index b0cdb70..21ba9a6 100644
--- a/mingling/src/parser/picker.rs
+++ b/mingling/src/parser/picker.rs
@@ -71,15 +71,12 @@ impl Picker {
where
TNext: Pickable<Output = TNext> + Default,
{
- let v = match TNext::pick(&mut self.args, val.into()) {
- Some(value) => value,
- None => {
- return PickWithRoute1 {
- args: self.args,
- val_1: TNext::default(),
- route: Some(route),
- };
- }
+ let Some(v) = TNext::pick(&mut self.args, val.into()) else {
+ return PickWithRoute1 {
+ args: self.args,
+ val_1: TNext::default(),
+ route: Some(route),
+ };
};
PickWithRoute1 {
args: self.args,
@@ -112,6 +109,7 @@ impl Picker {
/// Takes a closure that receives the current `Argument` and returns a new `Argument`.
/// The returned `Argument` replaces the original arguments in the builder.
/// This method can be used to modify or transform the parsed arguments before extracting values.
+ #[must_use]
pub fn operate_args<F: FnOnce(Argument) -> Argument>(mut self, operation: F) -> Self {
self.args = operation(self.args);
self
@@ -141,7 +139,7 @@ pub trait Pickable {
// Non-routed Pick structs (no R parameter, no route field)
/// Internal macro: generates the struct definition and common methods
-/// (after, after_or_route, operate_args) for non-routed Pick structs.
+/// (after, `after_or_route`, `operate_args`) for non-routed Pick structs.
macro_rules! define_pick_struct {
($n:ident $final:ident $final_val:ident $route_self:ident $($T:ident $val:ident),+ $(,)?) => {
#[doc(hidden)]
@@ -163,6 +161,7 @@ macro_rules! define_pick_struct {
/// Takes a closure that receives the last extracted value and returns a new value of the same type.
/// The transformed value replaces the original value in the builder.
/// This method can be used to modify or validate the extracted value before final unpacking.
+ #[must_use]
pub fn after<F>(mut self, mut edit: F) -> Self
where
F: FnMut($final) -> $final,
@@ -177,6 +176,7 @@ macro_rules! define_pick_struct {
/// If the closure returns `Ok(new_value)`, the new value replaces the original value in the builder.
/// If the closure returns `Err(route)`, the provided `route` is stored in the builder for later error handling.
/// If a route was already stored from a previous `pick_or_route` call, the existing route is preserved.
+ #[must_use]
pub fn after_or_route<F, R>(mut self, mut edit: F) -> $route_self<$($T,)+ R>
where
F: FnMut(&$final) -> Result<$final, R>,
@@ -205,6 +205,7 @@ macro_rules! define_pick_struct {
/// Takes a closure that receives the current `Argument` and returns a new `Argument`.
/// The returned `Argument` replaces the original arguments in the builder.
/// This method can be used to modify or transform the parsed arguments before extracting values.
+ #[must_use]
pub fn operate_args<F: FnOnce(Argument) -> Argument>(mut self, operation: F) -> Self {
self.args = operation(self.args);
self
@@ -359,17 +360,14 @@ macro_rules! impl_pick_next {
where
TNext: Pickable<Output = TNext> + Default,
{
- let v = match TNext::pick(&mut self.args, val.into()) {
- Some(value) => value,
- None => {
- return $route_next {
- args: self.args,
- $($val: self.$val,)+
- $next_val: TNext::default(),
- route: Some(route),
- };
- }
- };
+ let Some(v) = TNext::pick(&mut self.args, val.into()) else {
+ return $route_next {
+ args: self.args,
+ $($val: self.$val,)+
+ $next_val: TNext::default(),
+ route: Some(route),
+ };
+ };
$route_next {
args: self.args,
$($val: self.$val,)+
@@ -413,7 +411,7 @@ impl_pick_next! { Pick11 Pick12 val_12 PickWithRoute12 T1 val_1, T2 val_2, T3 va
// Routed PickWithRoute structs (with R parameter, route field)
/// Internal macro: generates the routed struct definition and common methods
-/// (after, after_or_route, operate_args) for PickWithRoute structs.
+/// (after, `after_or_route`, `operate_args`) for `PickWithRoute` structs.
macro_rules! define_pick_with_route_struct {
($n:ident $final:ident $final_val:ident $($T:ident $val:ident),+) => {
#[doc(hidden)]
@@ -436,6 +434,7 @@ macro_rules! define_pick_with_route_struct {
/// Takes a closure that receives the last extracted value and returns a new value of the same type.
/// The transformed value replaces the original value in the builder.
/// This method can be used to modify or validate the extracted value before final unpacking.
+ #[must_use]
pub fn after<F>(mut self, mut edit: F) -> Self
where
F: FnMut($final) -> $final,
@@ -450,6 +449,7 @@ macro_rules! define_pick_with_route_struct {
/// If the closure returns `Ok(new_value)`, the new value replaces the original value in the builder.
/// If the closure returns `Err(route)`, the provided `route` is stored in the builder for later error handling.
/// If a route was already stored from a previous `pick_or_route` call, the existing route is preserved.
+ #[must_use]
pub fn after_or_route<F>(mut self, mut edit: F) -> Self
where
F: FnMut(&$final) -> Result<$final, R>,
@@ -475,6 +475,7 @@ macro_rules! define_pick_with_route_struct {
/// Takes a closure that receives the current `Argument` and returns a new `Argument`.
/// The returned `Argument` replaces the original arguments in the builder.
/// This method can be used to modify or transform the parsed arguments before extracting values.
+ #[must_use]
pub fn operate_args<F: FnOnce(Argument) -> Argument>(mut self, operation: F) -> Self {
self.args = operation(self.args);
self
@@ -483,7 +484,7 @@ macro_rules! define_pick_with_route_struct {
};
}
-/// Internal macro: generates `From` impl for routed PickWithRouteN into a tuple.
+/// Internal macro: generates `From` impl for routed `PickWithRouteN` into a tuple.
macro_rules! impl_pick_with_route_from_tuple {
($n:ident $($T:ident $val:ident),+) => {
impl<$($T,)+ R> From<$n<$($T,)+ R>> for ($($T,)+)
@@ -497,7 +498,7 @@ macro_rules! impl_pick_with_route_from_tuple {
};
}
-/// Internal macro: generates `unpack` and `unpack_directly` for routed PickWithRouteN (N >= 2).
+/// Internal macro: generates `unpack` and `unpack_directly` for routed `PickWithRouteN` (N >= 2).
macro_rules! impl_pick_with_route_unpack_tuple {
($n:ident $($T:ident $val:ident),+) => {
impl<$($T,)+ R> $n<$($T,)+ R>
@@ -508,6 +509,10 @@ macro_rules! impl_pick_with_route_unpack_tuple {
///
/// Returns `Ok((T1, T2, ...))` if no route was stored.
/// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`.
+ ///
+ /// # Errors
+ ///
+ /// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`.
pub fn unpack(self) -> Result<($($T,)+), R> {
match self.route {
Some(route) => Err(route),
@@ -518,6 +523,7 @@ macro_rules! impl_pick_with_route_unpack_tuple {
/// Unpacks the builder into a tuple of extracted values.
///
/// Returns the tuple of extracted values regardless of route state.
+ #[must_use]
pub fn unpack_directly(self) -> ($($T,)+) {
($(self.$val,)+)
}
@@ -546,6 +552,10 @@ where
///
/// Returns `Ok(T1)` if no route was stored.
/// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`.
+ ///
+ /// # Errors
+ ///
+ /// Returns `Err(R)` if a route was stored via `pick_or_route` or `after_or_route`.
pub fn unpack(self) -> Result<T1, R> {
match self.route {
Some(route) => Err(route),
@@ -556,6 +566,7 @@ where
/// Unpacks the builder into the extracted value.
///
/// Returns the extracted value regardless of route state.
+ #[must_use]
pub fn unpack_directly(self) -> T1 {
self.val_1
}
@@ -650,6 +661,7 @@ macro_rules! impl_pick_with_route_next {
///
/// If a route was already stored from a previous `pick_or_route` or `after_or_route` call,
/// the existing route is preserved and the new `route` parameter is ignored.
+ #[allow(clippy::manual_let_else)]
pub fn pick_or_route<TNext>(mut self, val: impl Into<mingling_core::Flag>, route: R) -> $next<$($T,)+ TNext, R>
where
TNext: Pickable<Output = TNext> + Default,
diff --git a/mingling/src/parser/picker/bools.rs b/mingling/src/parser/picker/bools.rs
index aa2335a..ede8812 100644
--- a/mingling/src/parser/picker/bools.rs
+++ b/mingling/src/parser/picker/bools.rs
@@ -37,10 +37,12 @@ impl std::ops::Deref for Yes {
}
impl Yes {
+ #[must_use]
pub fn is_yes(&self) -> bool {
matches!(self, Yes::Yes)
}
+ #[must_use]
pub fn is_no(&self) -> bool {
matches!(self, Yes::No)
}
@@ -92,10 +94,12 @@ impl std::ops::Deref for True {
}
impl True {
+ #[must_use]
pub fn is_true(&self) -> bool {
matches!(self, True::True)
}
+ #[must_use]
pub fn is_false(&self) -> bool {
matches!(self, True::False)
}
diff --git a/mingling/src/parser/picker/builtin.rs b/mingling/src/parser/picker/builtin.rs
index e7a178d..6194955 100644
--- a/mingling/src/parser/picker/builtin.rs
+++ b/mingling/src/parser/picker/builtin.rs
@@ -68,7 +68,7 @@ impl Pickable for usize {
let picked = args.pick_argument(flag)?;
let size_parse = Size::from_str(picked.as_str());
match size_parse {
- Ok(size) => Some(size.bytes() as usize),
+ Ok(size) => usize::try_from(size.bytes()).ok(),
Err(_) => None,
}
}
@@ -84,7 +84,7 @@ impl Pickable for Vec<usize> {
for picked in picked_vec {
let size_parse = Size::from_str(picked.as_str());
match size_parse {
- Ok(size) => result.push(size.bytes() as usize),
+ Ok(size) => result.push(usize::try_from(size.bytes()).unwrap_or(usize::MAX)),
Err(_) => return None,
}
}
diff --git a/mingling/src/parser/picker/path.rs b/mingling/src/parser/picker/path.rs
index c97250f..961542e 100644
--- a/mingling/src/parser/picker/path.rs
+++ b/mingling/src/parser/picker/path.rs
@@ -91,7 +91,7 @@ impl<T: Into<PathBuf>> PathChecker for T where T: Into<PathBuf> {}
fn check_paths(path: impl Into<Vec<PathBuf>>, rule: &PathCheckRule) -> Result<(), ()> {
let paths = path.into();
- for p in paths.iter() {
+ for p in &paths {
check_exist(p, rule)?;
check_type(p, rule)?;
}
diff --git a/mingling/src/parser/picker/path/rule.rs b/mingling/src/parser/picker/path/rule.rs
index 07df705..bf5cab3 100644
--- a/mingling/src/parser/picker/path/rule.rs
+++ b/mingling/src/parser/picker/path/rule.rs
@@ -25,6 +25,7 @@ pub struct PathTypeCheck {
impl PathCheckRule {
/// Creates a new `PathCheckRule` with default values
+ #[must_use]
pub fn new() -> Self {
Self {
exist_check: None,
@@ -33,6 +34,7 @@ impl PathCheckRule {
}
/// Allows the path to be a file
+ #[must_use]
pub fn allow_file(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -55,6 +57,7 @@ impl PathCheckRule {
}
/// Allows the path to be a directory
+ #[must_use]
pub fn allow_dir(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -77,6 +80,7 @@ impl PathCheckRule {
}
/// Allows the path to be a symlink
+ #[must_use]
pub fn allow_symlink(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -99,6 +103,7 @@ impl PathCheckRule {
}
/// Denies the path from being a file
+ #[must_use]
pub fn deny_file(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -121,6 +126,7 @@ impl PathCheckRule {
}
/// Denies the path from being a directory
+ #[must_use]
pub fn deny_dir(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -143,6 +149,7 @@ impl PathCheckRule {
}
/// Denies the path from being a symlink
+ #[must_use]
pub fn deny_symlink(self) -> Self {
match self.type_check {
Some(type_check) => Self {
@@ -165,6 +172,7 @@ impl PathCheckRule {
}
/// Requires the path to be a file (overrides type checks)
+ #[must_use]
pub fn must_file(self) -> Self {
Self {
type_check: Some(PathTypeCheck {
@@ -177,6 +185,7 @@ impl PathCheckRule {
}
/// Requires the path to be a directory (overrides type checks)
+ #[must_use]
pub fn must_dir(self) -> Self {
Self {
type_check: Some(PathTypeCheck {
@@ -189,6 +198,7 @@ impl PathCheckRule {
}
/// Requires the path to be a symlink (overrides type checks)
+ #[must_use]
pub fn must_symlink(self) -> Self {
Self {
type_check: Some(PathTypeCheck {
@@ -201,6 +211,7 @@ impl PathCheckRule {
}
/// Requires the path to exist
+ #[must_use]
pub fn must_exist(self) -> Self {
Self {
exist_check: Some(PathExistCheck::Exists),
@@ -209,6 +220,7 @@ impl PathCheckRule {
}
/// Requires the path to not exist
+ #[must_use]
pub fn must_not_exist(self) -> Self {
Self {
exist_check: Some(PathExistCheck::NotExists),