From d16b48bfe1054226c3767a1c16482c00b330fa08 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 19 Oct 2023 17:49:00 -0700 Subject: [PATCH] fix clippy --- dsc/src/resource_command.rs | 4 +- dsc/src/subcommand.rs | 4 +- dsc_lib/src/dscresources/command_resource.rs | 2 +- dsc_lib/src/functions/base64.rs | 17 +++---- dsc_lib/src/functions/concat.rs | 16 +++---- dsc_lib/src/functions/mod.rs | 47 +++++++++++++++++--- dsc_lib/src/parser/expressions.rs | 18 +++++++- dsc_lib/src/parser/functions.rs | 30 ++++++++----- dsc_lib/src/parser/mod.rs | 46 +++++++++++++------ registry/src/main.rs | 2 +- registry/src/regconfighelper.rs | 4 +- 11 files changed, 133 insertions(+), 57 deletions(-) diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index b4d9494c7..e56430283 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -163,7 +163,7 @@ pub fn export(dsc: &mut DscManager, resource: &str, format: &Option (), + Ok(()) => (), Err(err) => { error!("Error: {err}"); exit(EXIT_DSC_ERROR); @@ -191,7 +191,7 @@ pub fn get_resource(dsc: &mut DscManager, resource: &str) -> DscResource { } match dsc.initialize_discovery() { - Ok(_) => (), + Ok(()) => (), Err(err) => { error!("Error: {err}"); exit(EXIT_DSC_ERROR); diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index 728199edb..3583537b4 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -273,7 +273,7 @@ pub fn validate_config(config: &str) { }; let properties = resource_block["properties"].clone(); let _result: Result<(), ValidationError> = match compiled_schema.validate(&properties) { - Ok(_) => Ok(()), + Ok(()) => Ok(()), Err(err) => { let mut error = String::new(); for e in err { @@ -304,7 +304,7 @@ pub fn resource(subcommand: &ResourceSubCommand, format: &Option, match subcommand { ResourceSubCommand::List { resource_name, description, tags } => { match dsc.initialize_discovery() { - Ok(_) => (), + Ok(()) => (), Err(err) => { error!("Error: {err}"); exit(EXIT_DSC_ERROR); diff --git a/dsc_lib/src/dscresources/command_resource.rs b/dsc_lib/src/dscresources/command_resource.rs index f5e7fec38..5dd36a14d 100644 --- a/dsc_lib/src/dscresources/command_resource.rs +++ b/dsc_lib/src/dscresources/command_resource.rs @@ -493,7 +493,7 @@ fn verify_json(resource: &ResourceManifest, cwd: &str, json: &str) -> Result<(), }; let json: Value = serde_json::from_str(json)?; let result = match compiled_schema.validate(&json) { - Ok(_) => Ok(()), + Ok(()) => Ok(()), Err(err) => { let mut error = String::new(); for e in err { diff --git a/dsc_lib/src/functions/base64.rs b/dsc_lib/src/functions/base64.rs index 2ee85503a..4a907e5e3 100644 --- a/dsc_lib/src/functions/base64.rs +++ b/dsc_lib/src/functions/base64.rs @@ -22,12 +22,9 @@ impl Function for Base64 { 1 } - fn invoke(&self, args: &Vec) -> Result { - let arg = match args.get(0).unwrap() { - FunctionArg::String(value) => value, - _ => { - return Err(DscError::Parser("Invalid argument type".to_string())); - } + fn invoke(&self, args: &[FunctionArg]) -> Result { + let FunctionArg::String(arg) = args.get(0).unwrap() else { + return Err(DscError::Parser("Invalid argument type".to_string())); }; Ok(FunctionResult::String(general_purpose::STANDARD.encode(arg))) } @@ -35,25 +32,25 @@ impl Function for Base64 { #[cfg(test)] mod tests { - use crate::parser::StatementParser; + use crate::parser::Statement; #[test] fn strings() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[base64('hello world')]").unwrap(); assert_eq!(result, "aGVsbG8gd29ybGQ="); } #[test] fn numbers() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[base64(123)]"); assert!(result.is_err()); } #[test] fn nested() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[base64(base64('hello world'))]").unwrap(); assert_eq!(result, "YUdWc2JHOGdkMjl5YkdRPQ=="); } diff --git a/dsc_lib/src/functions/concat.rs b/dsc_lib/src/functions/concat.rs index c9993dcf2..c6b510519 100644 --- a/dsc_lib/src/functions/concat.rs +++ b/dsc_lib/src/functions/concat.rs @@ -20,7 +20,7 @@ impl Function for Concat { vec![AcceptedArgKind::String, AcceptedArgKind::Integer] } - fn invoke(&self, args: &Vec) -> Result { + fn invoke(&self, args: &[FunctionArg]) -> Result { let mut result = String::new(); for arg in args { match arg { @@ -41,46 +41,46 @@ impl Function for Concat { #[cfg(test)] mod tests { - use crate::parser::StatementParser; + use crate::parser::Statement; #[test] fn strings() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('a', 'b')]").unwrap(); assert_eq!(result, "ab"); } #[test] fn strings_with_spaces() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('a ', ' ', ' b')]").unwrap(); assert_eq!(result, "a b"); } #[test] fn numbers() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat(1, 2)]").unwrap(); assert_eq!(result, "12"); } #[test] fn string_and_numbers() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('a', 1, 'b', 2)]").unwrap(); assert_eq!(result, "a1b2"); } #[test] fn nested() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('a', concat('b', 'c'), 'd')]").unwrap(); assert_eq!(result, "abcd"); } #[test] fn invalid_one_parameter() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('a')]"); assert!(result.is_err()); } diff --git a/dsc_lib/src/functions/mod.rs b/dsc_lib/src/functions/mod.rs index b5a4facd9..5a4ebdff5 100644 --- a/dsc_lib/src/functions/mod.rs +++ b/dsc_lib/src/functions/mod.rs @@ -9,6 +9,7 @@ use tracing::debug; pub mod base64; pub mod concat; +/// The kind of argument that a function accepts. #[derive(Debug, PartialEq)] pub enum AcceptedArgKind { String, @@ -16,18 +17,34 @@ pub enum AcceptedArgKind { Boolean, } +/// A function that can be invoked. pub trait Function { + /// The minimum number of arguments that the function accepts. fn min_args(&self) -> usize; + /// The maximum number of arguments that the function accepts. fn max_args(&self) -> usize; + /// The types of arguments that the function accepts. fn accepted_arg_types(&self) -> Vec; - fn invoke(&self, args: &Vec) -> Result; + /// Invoke the function. + /// + /// # Arguments + /// + /// * `args` - The arguments to the function. + /// + /// # Errors + /// + /// This function will return an error if the function fails to execute. + fn invoke(&self, args: &[FunctionArg]) -> Result; } +/// A dispatcher for functions. pub struct FunctionDispatcher { functions: HashMap>, } impl FunctionDispatcher { + /// Create a new `FunctionDispatcher` instance. + #[must_use] pub fn new() -> Self { let mut functions: HashMap> = HashMap::new(); functions.insert("base64".to_string(), Box::new(base64::Base64{})); @@ -37,33 +54,43 @@ impl FunctionDispatcher { } } + /// Invoke a function. + /// + /// # Arguments + /// + /// * `name` - The name of the function to invoke. + /// * `args` - The arguments to the function. + /// + /// # Errors + /// + /// This function will return an error if the function fails to execute. pub fn invoke(&self, name: &str, args: &Vec) -> Result { let function = self.functions.get(name); match function { Some(function) => { // check if arg number are valid if args.len() < function.min_args() { - return Err(DscError::Parser(format!("Function {0} requires at least {1} arguments", name, function.min_args()))); + return Err(DscError::Parser(format!("Function '{name}' requires at least {0} arguments", function.min_args()))); } if args.len() > function.max_args() { - return Err(DscError::Parser(format!("Function {0} requires at most {1} arguments", name, function.max_args()))); + return Err(DscError::Parser(format!("Function '{name}' requires at most {0} arguments", function.max_args()))); } // check if arg types are valid for arg in args { match arg { FunctionArg::String(_) => { if !function.accepted_arg_types().contains(&AcceptedArgKind::String) { - return Err(DscError::Parser(format!("Function {0} does not accept string arguments", name))); + return Err(DscError::Parser(format!("Function '{name}' does not accept string arguments"))); } }, FunctionArg::Integer(_) => { if !function.accepted_arg_types().contains(&AcceptedArgKind::Integer) { - return Err(DscError::Parser(format!("Function {0} does not accept integer arguments", name))); + return Err(DscError::Parser(format!("Function '{name}' does not accept integer arguments"))); } }, FunctionArg::Boolean(_) => { if !function.accepted_arg_types().contains(&AcceptedArgKind::Boolean) { - return Err(DscError::Parser(format!("Function {0} does not accept boolean arguments", name))); + return Err(DscError::Parser(format!("Function '{name}' does not accept boolean arguments"))); } }, FunctionArg::Expression(_) => { @@ -76,7 +103,13 @@ impl FunctionDispatcher { function.invoke(args) }, - None => Err(DscError::Parser(format!("Unknown function {0}", name))), + None => Err(DscError::Parser(format!("Unknown function '{name}'"))), } } } + +impl Default for FunctionDispatcher { + fn default() -> Self { + Self::new() + } +} diff --git a/dsc_lib/src/parser/expressions.rs b/dsc_lib/src/parser/expressions.rs index f52316c67..f279997fb 100644 --- a/dsc_lib/src/parser/expressions.rs +++ b/dsc_lib/src/parser/expressions.rs @@ -13,6 +13,17 @@ pub struct Expression<'a> { } impl<'a> Expression<'a> { + /// Create a new `Expression` instance. + /// + /// # Arguments + /// + /// * `function_dispatcher` - The function dispatcher to use. + /// * `statement` - The statement that the expression is part of. + /// * `expression` - The expression node. + /// + /// # Errors + /// + /// This function will return an error if the expression node is not valid. pub fn new(function_dispatcher: &'a FunctionDispatcher, statement: &str, expression: &Node) -> Result { let Some(function) = expression.child_by_field_name("function") else { return Err(DscError::Parser("Function node not found".to_string())); @@ -42,6 +53,11 @@ impl<'a> Expression<'a> { }) } + /// Invoke the expression. + /// + /// # Errors + /// + /// This function will return an error if the expression fails to execute. pub fn invoke(&self) -> Result { let result = self.function.invoke()?; if let Some(member_access) = &self.member_access { @@ -52,7 +68,7 @@ impl<'a> Expression<'a> { FunctionResult::Object(object) => { let mut value = object; if !value.is_object() { - return Err(DscError::Parser(format!("Member access on non-object value {0}", value.to_string()))); + return Err(DscError::Parser(format!("Member access on non-object value '{value}'"))); } for member in member_access { value = value[member].clone(); diff --git a/dsc_lib/src/parser/functions.rs b/dsc_lib/src/parser/functions.rs index 7dbe199dd..5a646b113 100644 --- a/dsc_lib/src/parser/functions.rs +++ b/dsc_lib/src/parser/functions.rs @@ -32,6 +32,17 @@ pub enum FunctionResult { } impl<'a> Function<'a> { + /// Create a new `Function` instance. + /// + /// # Arguments + /// + /// * `function_dispatcher` - The function dispatcher to use. + /// * `statement` - The statement that the function is part of. + /// * `function` - The function node. + /// + /// # Errors + /// + /// This function will return an error if the function node is not valid. pub fn new(function_dispatcher: &'a FunctionDispatcher, statement: &str, function: &Node) -> Result { let Some(function_name) = function.child_by_field_name("name") else { return Err(DscError::Parser("Function name node not found".to_string())); @@ -44,30 +55,29 @@ impl<'a> Function<'a> { args}) } + /// Invoke the function. + /// + /// # Errors + /// + /// This function will return an error if the function fails to execute. pub fn invoke(&self) -> Result { // if any args are expressions, we need to invoke those first - let mut resolved_args: Option> = None; + let mut resolved_args: Vec = vec![]; if let Some(args) = &self.args { - resolved_args = Some(vec![]); for arg in args { match arg { FunctionArg::Expression(expression) => { let value = expression.invoke()?; - resolved_args.as_mut().unwrap().push(FunctionArg::String(value)); + resolved_args.push(FunctionArg::String(value)); }, _ => { - resolved_args.as_mut().unwrap().push(arg.clone()); + resolved_args.push(arg.clone()); } } } } - let args = match resolved_args { - Some(args) => args, - None => vec![], - }; - - self.function_dispatcher.invoke(&self.name, &args) + self.function_dispatcher.invoke(&self.name, &resolved_args) } } diff --git a/dsc_lib/src/parser/mod.rs b/dsc_lib/src/parser/mod.rs index d98f40f93..8dca4c96d 100644 --- a/dsc_lib/src/parser/mod.rs +++ b/dsc_lib/src/parser/mod.rs @@ -9,12 +9,17 @@ use expressions::Expression; pub mod expressions; pub mod functions; -pub struct StatementParser { +pub struct Statement { parser: Parser, function_dispatcher: FunctionDispatcher, } -impl StatementParser { +impl Statement { + /// Create a new `StatementParser` instance. + /// + /// # Errors + /// + /// This function will return an error if the underlying parser fails to initialize. pub fn new() -> Result { let mut parser = Parser::new(); parser.set_language(tree_sitter_dscexpression::language())?; @@ -25,8 +30,19 @@ impl StatementParser { }) } + /// Parse and execute a statement. + /// + /// # Arguments + /// + /// * `statement` - The statement to parse and execute. + /// + /// # Errors + /// + /// This function will return an error if the statement fails to parse or execute. pub fn parse_and_execute(&mut self, statement: &str) -> Result { - let tree = &mut self.parser.parse(statement, None).unwrap(); + let Some(tree) = &mut self.parser.parse(statement, None) else { + return Err(DscError::Parser("Error parsing statement".to_string())); + }; let root_node = tree.root_node(); if root_node.is_error() { return Err(DscError::Parser("Error parsing statement root".to_string())); @@ -39,17 +55,21 @@ impl StatementParser { return Err(DscError::Parser("Child node not found".to_string())); }; if child_node.is_error() { - return Err(DscError::Parser("Error parsing statement".to_string())); + return Err(DscError::Parser("Error parsing statement child".to_string())); } let kind = child_node.kind(); match kind { "stringLiteral" | "bracketInStringLiteral" => { - let value = child_node.utf8_text(statement.as_bytes()).unwrap(); + let Ok(value) = child_node.utf8_text(statement.as_bytes()) else { + return Err(DscError::Parser("Error parsing string literal".to_string())); + }; Ok(value.to_string()) }, "escapedStringLiteral" => { // need to remove the first character: [[ => [ - let value = child_node.utf8_text(statement.as_bytes()).unwrap(); + let Ok(value) = child_node.utf8_text(statement.as_bytes()) else { + return Err(DscError::Parser("Error parsing escaped string literal".to_string())); + }; Ok(value[1..].to_string()) }, "expression" => { @@ -69,49 +89,49 @@ mod tests { #[test] fn string_literal() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("this is a string").unwrap(); assert_eq!(result, "this is a string"); } #[test] fn bracket_string() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[[this is a string]").unwrap(); assert_eq!(result, "[this is a string]"); } #[test] fn bracket_in_string() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[this] is a string").unwrap(); assert_eq!(result, "[this] is a string"); } #[test] fn invalid_function() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[invalid()]"); assert!(result.is_err()); } #[test] fn nonquoted_string_parameter() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat(abc)]"); assert!(result.is_err()); } #[test] fn missing_endquote_string_parameter() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('abc)]"); assert!(result.is_err()); } #[test] fn empty_parameter() { - let mut parser = StatementParser::new().unwrap(); + let mut parser = Statement::new().unwrap(); let result = parser.parse_and_execute("[concat('abc', , 'def')]"); assert!(result.is_err()); } diff --git a/registry/src/main.rs b/registry/src/main.rs index 0562f61f2..0912d4fd9 100644 --- a/registry/src/main.rs +++ b/registry/src/main.rs @@ -91,7 +91,7 @@ fn main() { args::SubCommand::Config { subcommand } => { let json: String; match regconfighelper::validate_config(&config) { - Ok(_) => {}, + Ok(()) => {}, Err(err) => { eprintln!("Error validating config: {err}"); exit(EXIT_INVALID_INPUT); diff --git a/registry/src/regconfighelper.rs b/registry/src/regconfighelper.rs index c02c7fa45..3d1167de9 100644 --- a/registry/src/regconfighelper.rs +++ b/registry/src/regconfighelper.rs @@ -99,7 +99,7 @@ pub fn config_set(config: &Registry) -> Result { None => { // just verify that the value exists match reg_key.get_value(value_name) { - Ok(_) => {}, + Ok(()) => {}, Err(NtStatusError { status: NtStatusErrorKind::ObjectNameNotFound, .. }) => { reg_key.set_value(value_name, &NtRegistryValueData::None)?; }, @@ -114,7 +114,7 @@ pub fn config_set(config: &Registry) -> Result { reg_key = open_or_create_key(&config.key_path)?; reg_result.exist = Some(false); match reg_key.delete_value(value_name) { - Ok(_) | Err(NtStatusError { status: NtStatusErrorKind::ObjectNameNotFound, ..}) => {}, + Ok(()) | Err(NtStatusError { status: NtStatusErrorKind::ObjectNameNotFound, ..}) => {}, Err(err) => { return Err(RegistryError::NtStatus(err)); }