diff options
Diffstat (limited to 'mingling/src/parser')
| -rw-r--r-- | mingling/src/parser/args.rs | 40 | ||||
| -rw-r--r-- | mingling/src/parser/picker.rs | 60 | ||||
| -rw-r--r-- | mingling/src/parser/picker/bools.rs | 4 | ||||
| -rw-r--r-- | mingling/src/parser/picker/builtin.rs | 4 | ||||
| -rw-r--r-- | mingling/src/parser/picker/path.rs | 2 | ||||
| -rw-r--r-- | mingling/src/parser/picker/path/rule.rs | 12 |
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), |
