diff --git a/dsc/src/main.rs b/dsc/src/main.rs index e28a48e7..eb4cba19 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -71,7 +71,7 @@ fn main() { exit(util::EXIT_JSON_ERROR); } }; - util::write_output(&json, &format); + util::write_output(&json, format.as_ref()); }, } diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index b1fdd0d8..69f5915f 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -47,7 +47,7 @@ pub fn get(dsc: &DscManager, resource_type: &str, mut input: String, format: &Op exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); } Err(err) => { error!("Error: {err}"); @@ -100,7 +100,7 @@ pub fn get_all(dsc: &DscManager, resource_type: &str, format: &Option { error!("Error: {err}"); @@ -187,7 +187,7 @@ pub fn test(dsc: &DscManager, resource_type: &str, mut input: String, format: &O exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); } Err(err) => { error!("Error: {err}"); @@ -247,7 +247,7 @@ pub fn schema(dsc: &DscManager, resource_type: &str, format: &Option { error!("Error: {err}"); @@ -293,7 +293,7 @@ pub fn export(dsc: &mut DscManager, resource_type: &str, format: &Option exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); } else { let json = match serde_json::to_string(&result) { @@ -53,7 +53,7 @@ pub fn config_get(configurator: &mut Configurator, format: &Option exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); if result.had_errors { exit(EXIT_DSC_ERROR); } @@ -78,7 +78,7 @@ pub fn config_set(configurator: &mut Configurator, format: &Option exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); } else { let json = match serde_json::to_string(&result) { @@ -88,7 +88,7 @@ pub fn config_set(configurator: &mut Configurator, format: &Option exit(EXIT_JSON_ERROR); } }; - write_output(&json, format); + write_output(&json, format.as_ref()); if result.had_errors { exit(EXIT_DSC_ERROR); } @@ -164,7 +164,7 @@ pub fn config_test(configurator: &mut Configurator, format: &Option) -> Option { +fn initialize_config_root(path: Option<&String>) -> Option { // code that calls this pass in either None, Some("-"), or Some(path) // in the case of `-` we treat it as None, but need to pass it back as subsequent processing needs to handle it let use_stdin = if let Some(specified_path) = path { @@ -254,7 +254,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro ConfigSubCommand::Test { input, file, .. } | ConfigSubCommand::Validate { input, file, .. } | ConfigSubCommand::Export { input, file, .. } => { - let new_path = initialize_config_root(file); + let new_path = initialize_config_root(file.as_ref()); let document = get_input(input, &new_path); if *as_include { let (new_parameters, config_json) = match get_contents(&document) { @@ -270,7 +270,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro } }, ConfigSubCommand::Resolve { input, file, .. } => { - let new_path = initialize_config_root(file); + let new_path = initialize_config_root(file.as_ref()); let document = get_input(input, &new_path); let (new_parameters, config_json) = match get_contents(&document) { Ok((parameters, config_json)) => (parameters, config_json), @@ -331,7 +331,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro } }; - if let Err(err) = configurator.set_context(¶meters) { + if let Err(err) = configurator.set_context(parameters.as_ref()) { error!("Error: Parameter input failure: {err}"); exit(EXIT_INVALID_INPUT); } @@ -352,7 +352,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro reason: None, }; if *as_include { - let new_path = initialize_config_root(file); + let new_path = initialize_config_root(file.as_ref()); let input = get_input(input, &new_path); match serde_json::from_str::(&input) { Ok(_) => { @@ -380,7 +380,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro exit(EXIT_JSON_ERROR); }; - write_output(&json, format); + write_output(&json, format.as_ref()); }, ConfigSubCommand::Export { output_format, .. } => { config_export(&mut configurator, output_format); @@ -414,7 +414,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, as_gro exit(EXIT_JSON_ERROR); } }; - write_output(&json_string, output_format); + write_output(&json_string, output_format.as_ref()); }, } } @@ -520,7 +520,7 @@ pub fn resource(subcommand: &ResourceSubCommand) { match subcommand { ResourceSubCommand::List { resource_name, adapter_name, description, tags, output_format } => { - list_resources(&mut dsc, resource_name, adapter_name, description, tags, output_format); + list_resources(&mut dsc, resource_name.as_ref(), adapter_name.as_ref(), description.as_ref(), tags.as_ref(), output_format.as_ref()); }, ResourceSubCommand::Schema { resource , output_format } => { dsc.find_resources(&[resource.to_string()]); @@ -556,14 +556,14 @@ pub fn resource(subcommand: &ResourceSubCommand) { } } -fn list_resources(dsc: &mut DscManager, resource_name: &Option, adapter_name: &Option, description: &Option, tags: &Option>, format: &Option) { +fn list_resources(dsc: &mut DscManager, resource_name: Option<&String>, adapter_name: Option<&String>, description: Option<&String>, tags: Option<&Vec>, format: Option<&OutputFormat>) { let mut write_table = false; let mut table = Table::new(&["Type", "Kind", "Version", "Caps", "RequireAdapter", "Description"]); if format.is_none() && io::stdout().is_terminal() { // write as table if format is not specified and interactive write_table = true; } - for resource in dsc.list_available_resources(&resource_name.clone().unwrap_or("*".to_string()), &adapter_name.clone().unwrap_or_default()) { + for resource in dsc.list_available_resources(resource_name.unwrap_or(&String::from("*")), adapter_name.unwrap_or(&String::from("*"))) { let mut capabilities = "--------".to_string(); let capability_types = [ (Capability::Get, "g"), @@ -594,7 +594,7 @@ fn list_resources(dsc: &mut DscManager, resource_name: &Option, adapter_ // if description is specified, skip if resource description does not contain it if description.is_some() && - (manifest.description.is_none() | !manifest.description.unwrap_or_default().to_lowercase().contains(&description.as_ref().unwrap_or(&String::new()).to_lowercase())) { + (manifest.description.is_none() | !manifest.description.unwrap_or_default().to_lowercase().contains(&description.as_ref().unwrap_or(&&String::new()).to_lowercase())) { continue; } diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 4c8e3771..73d6576c 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -190,18 +190,18 @@ pub fn get_schema(dsc_type: DscType) -> RootSchema { /// /// * `json` - The JSON to write /// * `format` - The format to use -pub fn write_output(json: &str, format: &Option) { +pub fn write_output(json: &str, format: Option<&OutputFormat>) { let mut is_json = true; - let mut output_format = format.clone(); + let mut output_format = format; let mut syntax_color = false; if std::io::stdout().is_terminal() { syntax_color = true; if output_format.is_none() { - output_format = Some(OutputFormat::Yaml); + output_format = Some(&OutputFormat::Yaml); } } else if output_format.is_none() { - output_format = Some(OutputFormat::Json); + output_format = Some(&OutputFormat::Json); } let output = match output_format { diff --git a/dsc_lib/src/configure/mod.rs b/dsc_lib/src/configure/mod.rs index 3a5d84a3..2898b905 100644 --- a/dsc_lib/src/configure/mod.rs +++ b/dsc_lib/src/configure/mod.rs @@ -161,7 +161,7 @@ fn add_metadata(kind: &Kind, mut properties: Option> ) -> Res Ok(serde_json::to_string(&properties)?) } -fn check_security_context(metadata: &Option) -> Result<(), DscError> { +fn check_security_context(metadata: Option<&Metadata>) -> Result<(), DscError> { if metadata.is_none() { return Ok(()); } @@ -241,7 +241,7 @@ impl Configurator { for resource in resources { Span::current().pb_inc(1); pb_span.pb_set_message(format!("Get '{}'", resource.name).as_str()); - let properties = self.invoke_property_expressions(&resource.properties)?; + let properties = self.invoke_property_expressions(resource.properties.as_ref())?; let Some(dsc_resource) = self.discovery.find_resource(&resource.resource_type) else { return Err(DscError::ResourceNotFound(resource.resource_type)); }; @@ -299,7 +299,7 @@ impl Configurator { for resource in resources { Span::current().pb_inc(1); pb_span.pb_set_message(format!("Set '{}'", resource.name).as_str()); - let properties = self.invoke_property_expressions(&resource.properties)?; + let properties = self.invoke_property_expressions(resource.properties.as_ref())?; let Some(dsc_resource) = self.discovery.find_resource(&resource.resource_type) else { return Err(DscError::ResourceNotFound(resource.resource_type)); }; @@ -407,7 +407,7 @@ impl Configurator { for resource in resources { Span::current().pb_inc(1); pb_span.pb_set_message(format!("Test '{}'", resource.name).as_str()); - let properties = self.invoke_property_expressions(&resource.properties)?; + let properties = self.invoke_property_expressions(resource.properties.as_ref())?; let Some(dsc_resource) = self.discovery.find_resource(&resource.resource_type) else { return Err(DscError::ResourceNotFound(resource.resource_type)); }; @@ -463,7 +463,7 @@ impl Configurator { for resource in &resources { Span::current().pb_inc(1); pb_span.pb_set_message(format!("Export '{}'", resource.name).as_str()); - let properties = self.invoke_property_expressions(&resource.properties)?; + let properties = self.invoke_property_expressions(resource.properties.as_ref())?; let Some(dsc_resource) = self.discovery.find_resource(&resource.resource_type) else { return Err(DscError::ResourceNotFound(resource.resource_type.clone())); }; @@ -488,14 +488,14 @@ impl Configurator { /// # Errors /// /// This function will return an error if the parameters are invalid. - pub fn set_context(&mut self, parameters_input: &Option) -> Result<(), DscError> { + pub fn set_context(&mut self, parameters_input: Option<&Value>) -> Result<(), DscError> { let config = serde_json::from_str::(self.json.as_str())?; self.set_parameters(parameters_input, &config)?; self.set_variables(&config)?; Ok(()) } - fn set_parameters(&mut self, parameters_input: &Option, config: &Configuration) -> Result<(), DscError> { + fn set_parameters(&mut self, parameters_input: Option<&Value>, config: &Configuration) -> Result<(), DscError> { // set default parameters first let Some(parameters) = &config.parameters else { if parameters_input.is_none() { @@ -636,7 +636,7 @@ impl Configurator { fn validate_config(&mut self) -> Result<(), DscError> { let config: Configuration = serde_json::from_str(self.json.as_str())?; - check_security_context(&config.metadata)?; + check_security_context(config.metadata.as_ref())?; // Perform discovery of resources used in config let required_resources = config.resources.iter().map(|p| p.resource_type.clone()).collect::>(); @@ -645,7 +645,7 @@ impl Configurator { Ok(()) } - fn invoke_property_expressions(&mut self, properties: &Option>) -> Result>, DscError> { + fn invoke_property_expressions(&mut self, properties: Option<&Map>) -> Result>, DscError> { debug!("Invoke property expressions"); if properties.is_none() { return Ok(None); @@ -657,7 +657,7 @@ impl Configurator { trace!("Invoke property expression for {name}: {value}"); match value { Value::Object(object) => { - let value = self.invoke_property_expressions(&Some(object.clone()))?; + let value = self.invoke_property_expressions(Some(&object.clone()))?; result.insert(name.clone(), serde_json::to_value(value)?); continue; }, @@ -666,7 +666,7 @@ impl Configurator { for element in array { match element { Value::Object(object) => { - let value = self.invoke_property_expressions(&Some(object.clone()))?; + let value = self.invoke_property_expressions(Some(&object.clone()))?; result_array.push(serde_json::to_value(value)?); continue; }, diff --git a/dsc_lib/src/discovery/command_discovery.rs b/dsc_lib/src/discovery/command_discovery.rs index 45644c7d..66195281 100644 --- a/dsc_lib/src/discovery/command_discovery.rs +++ b/dsc_lib/src/discovery/command_discovery.rs @@ -233,7 +233,7 @@ impl ResourceDiscovery for CommandDiscovery { let mut adapter_resources_count = 0; // invoke the list command let list_command = manifest.adapter.unwrap().list; - let (exit_code, stdout, stderr) = match invoke_command(&list_command.executable, list_command.args, None, Some(&adapter.directory), None, &manifest.exit_codes) + let (exit_code, stdout, stderr) = match invoke_command(&list_command.executable, list_command.args, None, Some(&adapter.directory), None, manifest.exit_codes.as_ref()) { Ok((exit_code, stdout, stderr)) => (exit_code, stdout, stderr), Err(e) => { diff --git a/dsc_lib/src/dscresources/command_resource.rs b/dsc_lib/src/dscresources/command_resource.rs index f8cdbc55..556cb73e 100644 --- a/dsc_lib/src/dscresources/command_resource.rs +++ b/dsc_lib/src/dscresources/command_resource.rs @@ -30,14 +30,14 @@ pub fn invoke_get(resource: &ResourceManifest, cwd: &str, filter: &str) -> Resul let Some(get) = &resource.get else { return Err(DscError::NotImplemented("get".to_string())); }; - let args = process_args(&get.args, filter); + let args = process_args(get.args.as_ref(), filter); if !filter.is_empty() { verify_json(resource, cwd, filter)?; - command_input = get_command_input(&get.input, filter)?; + command_input = get_command_input(get.input.as_ref(), filter)?; } info!("Invoking get '{}' using '{}'", &resource.resource_type, &get.executable); - let (_exit_code, stdout, stderr) = invoke_command(&get.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (_exit_code, stdout, stderr) = invoke_command(&get.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; if resource.kind == Some(Kind::Resource) { debug!("Verifying output of get '{}' using '{}'", &resource.resource_type, &get.executable); verify_json(resource, cwd, &stdout)?; @@ -134,11 +134,11 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te let Some(get) = &resource.get else { return Err(DscError::NotImplemented("get".to_string())); }; - let args = process_args(&get.args, desired); - let command_input = get_command_input(&get.input, desired)?; + let args = process_args(get.args.as_ref(), desired); + let command_input = get_command_input(get.input.as_ref(), desired)?; info!("Getting current state for set by invoking get '{}' using '{}'", &resource.resource_type, &get.executable); - let (exit_code, stdout, stderr) = invoke_command(&get.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (exit_code, stdout, stderr) = invoke_command(&get.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; if resource.kind == Some(Kind::Resource) { debug!("Verifying output of get '{}' using '{}'", &resource.resource_type, &get.executable); @@ -154,7 +154,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te let mut env: Option> = None; let mut input_desired: Option<&str> = None; - let args = process_args(&set.args, desired); + let args = process_args(set.args.as_ref(), desired); match &set.input { Some(InputKind::Env) => { env = Some(json_to_hashmap(desired)?); @@ -168,7 +168,7 @@ pub fn invoke_set(resource: &ResourceManifest, cwd: &str, desired: &str, skip_te } info!("Invoking {} '{}' using '{}'", operation_type, &resource.resource_type, &set.executable); - let (exit_code, stdout, stderr) = invoke_command(&set.executable, args, input_desired, Some(cwd), env, &resource.exit_codes)?; + let (exit_code, stdout, stderr) = invoke_command(&set.executable, args, input_desired, Some(cwd), env, resource.exit_codes.as_ref())?; match set.returns { Some(ReturnKind::State) => { @@ -256,11 +256,11 @@ pub fn invoke_test(resource: &ResourceManifest, cwd: &str, expected: &str) -> Re verify_json(resource, cwd, expected)?; - let args = process_args(&test.args, expected); - let command_input = get_command_input(&test.input, expected)?; + let args = process_args(test.args.as_ref(), expected); + let command_input = get_command_input(test.input.as_ref(), expected)?; info!("Invoking test '{}' using '{}'", &resource.resource_type, &test.executable); - let (exit_code, stdout, stderr) = invoke_command(&test.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (exit_code, stdout, stderr) = invoke_command(&test.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; if resource.kind == Some(Kind::Resource) { debug!("Verifying output of test '{}' using '{}'", &resource.resource_type, &test.executable); @@ -376,11 +376,11 @@ pub fn invoke_delete(resource: &ResourceManifest, cwd: &str, filter: &str) -> Re verify_json(resource, cwd, filter)?; - let args = process_args(&delete.args, filter); - let command_input = get_command_input(&delete.input, filter)?; + let args = process_args(delete.args.as_ref(), filter); + let command_input = get_command_input(delete.input.as_ref(), filter)?; info!("Invoking delete '{}' using '{}'", &resource.resource_type, &delete.executable); - let (_exit_code, _stdout, _stderr) = invoke_command(&delete.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (_exit_code, _stdout, _stderr) = invoke_command(&delete.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; Ok(()) } @@ -407,11 +407,11 @@ pub fn invoke_validate(resource: &ResourceManifest, cwd: &str, config: &str) -> return Err(DscError::NotImplemented("validate".to_string())); }; - let args = process_args(&validate.args, config); - let command_input = get_command_input(&validate.input, config)?; + let args = process_args(validate.args.as_ref(), config); + let command_input = get_command_input(validate.input.as_ref(), config)?; info!("Invoking validate '{}' using '{}'", &resource.resource_type, &validate.executable); - let (_exit_code, stdout, _stderr) = invoke_command(&validate.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (_exit_code, stdout, _stderr) = invoke_command(&validate.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; let result: ValidateResult = serde_json::from_str(&stdout)?; Ok(result) } @@ -432,7 +432,7 @@ pub fn get_schema(resource: &ResourceManifest, cwd: &str) -> Result { - let (_exit_code, stdout, _stderr) = invoke_command(&command.executable, command.args.clone(), None, Some(cwd), None, &resource.exit_codes)?; + let (_exit_code, stdout, _stderr) = invoke_command(&command.executable, command.args.clone(), None, Some(cwd), None, resource.exit_codes.as_ref())?; Ok(stdout) }, SchemaKind::Embedded(ref schema) => { @@ -468,15 +468,15 @@ pub fn invoke_export(resource: &ResourceManifest, cwd: &str, input: Option<&str> if !input.is_empty() { verify_json(resource, cwd, input)?; - command_input = get_command_input(&export.input, input)?; + command_input = get_command_input(export.input.as_ref(), input)?; } - args = process_args(&export.args, input); + args = process_args(export.args.as_ref(), input); } else { - args = process_args(&export.args, ""); + args = process_args(export.args.as_ref(), ""); } - let (_exit_code, stdout, stderr) = invoke_command(&export.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (_exit_code, stdout, stderr) = invoke_command(&export.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; let mut instances: Vec = Vec::new(); for line in stdout.lines() { @@ -518,11 +518,11 @@ pub fn invoke_resolve(resource: &ResourceManifest, cwd: &str, input: &str) -> Re return Err(DscError::Operation(format!("Resolve is not supported by resource {}", &resource.resource_type))); }; - let args = process_args(&resolve.args, input); - let command_input = get_command_input(&resolve.input, input)?; + let args = process_args(resolve.args.as_ref(), input); + let command_input = get_command_input(resolve.input.as_ref(), input)?; info!("Invoking resolve '{}' using '{}'", &resource.resource_type, &resolve.executable); - let (_exit_code, stdout, _stderr) = invoke_command(&resolve.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, &resource.exit_codes)?; + let (_exit_code, stdout, _stderr) = invoke_command(&resolve.executable, args, command_input.stdin.as_deref(), Some(cwd), command_input.env, resource.exit_codes.as_ref())?; let result: ResolveResult = serde_json::from_str(&stdout)?; Ok(result) } @@ -542,7 +542,7 @@ pub fn invoke_resolve(resource: &ResourceManifest, cwd: &str, input: &str) -> Re /// /// Error is returned if the command fails to execute or stdin/stdout/stderr cannot be opened. /// -async fn run_process_async(executable: &str, args: Option>, input: Option<&str>, cwd: Option<&str>, env: Option>, exit_codes: &Option>) -> Result<(i32, String, String), DscError> { +async fn run_process_async(executable: &str, args: Option>, input: Option<&str>, cwd: Option<&str>, env: Option>, exit_codes: Option<&HashMap>) -> Result<(i32, String, String), DscError> { // use somewhat large initial buffer to avoid early string reallocations; // the value is based on list result of largest of built-in adapters - WMI adapter ~500KB @@ -659,7 +659,7 @@ async fn run_process_async(executable: &str, args: Option>, input: O /// Will panic if tokio runtime can't be created. /// #[allow(clippy::implicit_hasher)] -pub fn invoke_command(executable: &str, args: Option>, input: Option<&str>, cwd: Option<&str>, env: Option>, exit_codes: &Option>) -> Result<(i32, String, String), DscError> { +pub fn invoke_command(executable: &str, args: Option>, input: Option<&str>, cwd: Option<&str>, env: Option>, exit_codes: Option<&HashMap>) -> Result<(i32, String, String), DscError> { debug!("Invoking command '{}' with args {:?}", executable, args); tokio::runtime::Builder::new_multi_thread() @@ -669,7 +669,7 @@ pub fn invoke_command(executable: &str, args: Option>, input: Option .block_on(run_process_async(executable, args, input, cwd, env, exit_codes)) } -fn process_args(args: &Option>, value: &str) -> Option> { +fn process_args(args: Option<&Vec>, value: &str) -> Option> { let Some(arg_values) = args else { debug!("No args to process"); return None; @@ -700,7 +700,7 @@ struct CommandInput { stdin: Option, } -fn get_command_input(input_kind: &Option, input: &str) -> Result { +fn get_command_input(input_kind: Option<&InputKind>, input: &str) -> Result { let mut env: Option> = None; let mut stdin: Option = None; match input_kind { diff --git a/dsc_lib/src/parser/functions.rs b/dsc_lib/src/parser/functions.rs index 176de113..f03b49ef 100644 --- a/dsc_lib/src/parser/functions.rs +++ b/dsc_lib/src/parser/functions.rs @@ -51,7 +51,7 @@ impl Function { let Some(name) = function_name else { return Err(DscError::Parser("Function name node not found".to_string())); }; - let args = convert_args_node(statement_bytes, &function_args)?; + let args = convert_args_node(statement_bytes, function_args.as_ref())?; let name = name.utf8_text(statement_bytes)?; debug!("Function name: {0}", name); Ok(Function{ @@ -87,7 +87,7 @@ impl Function { } } -fn convert_args_node(statement_bytes: &[u8], args: &Option) -> Result>, DscError> { +fn convert_args_node(statement_bytes: &[u8], args: Option<&Node>) -> Result>, DscError> { let Some(args) = args else { return Ok(None); };