diff --git a/src/flow_service/mod.rs b/src/flow_service/mod.rs index bc20af1..d442e4d 100644 --- a/src/flow_service/mod.rs +++ b/src/flow_service/mod.rs @@ -5,7 +5,7 @@ use crate::{ use tonic::{Extensions, Request, transport::Channel}; use tucana::{ aquila::{ModuleUpdateRequest, module_service_client::ModuleServiceClient}, - shared::Module, + shared::{Module, ModuleDefinition}, }; pub mod auth; @@ -18,6 +18,11 @@ pub struct FlowUpdateService { definition_source: Option, } +pub struct ModuleDefinitionAppendix { + pub module_identifier: String, + pub definitions: Vec, +} + impl FlowUpdateService { /// Create a new FlowUpdateService instance from an Aquila URL and a definition path. /// @@ -43,6 +48,11 @@ impl FlowUpdateService { } } + pub fn with_appendix(mut self, appendices: Vec) -> Self { + append_definitions_to_matching_modules(&mut self.modules, appendices); + self + } + pub fn with_definition_source(mut self, source: String) -> Self { self.definition_source = Some(source); self @@ -97,6 +107,19 @@ impl FlowUpdateService { } } +fn append_definitions_to_matching_modules( + modules: &mut [Module], + appendices: Vec, +) { + for appendix in appendices { + for module in modules.iter_mut() { + if module.identifier == appendix.module_identifier { + module.definitions.extend(appendix.definitions.clone()); + } + } + } +} + fn apply_definition_source_to_module(mut module: Module, source: String) -> Module { for data_type in &mut module.definition_data_types { data_type.definition_source = source.clone(); @@ -116,3 +139,80 @@ fn apply_definition_source_to_module(mut module: Module, source: String) -> Modu module } + +#[cfg(test)] +mod tests { + use super::*; + + fn module(identifier: &str) -> Module { + Module { + identifier: identifier.to_string(), + name: Vec::new(), + description: Vec::new(), + documentation: String::new(), + author: String::new(), + icon: String::new(), + version: String::new(), + flow_types: Vec::new(), + runtime_flow_types: Vec::new(), + function_definitions: Vec::new(), + runtime_function_definitions: Vec::new(), + definition_data_types: Vec::new(), + configurations: Vec::new(), + definitions: Vec::new(), + } + } + + fn definition(identifier: &str) -> ModuleDefinition { + ModuleDefinition { + flow_type_identifier: vec![identifier.to_string()], + value: None, + } + } + + #[test] + fn appends_appendix_definitions_to_all_modules_with_same_identifier() { + let mut modules = vec![module("shared"), module("other"), module("shared")]; + let appendices = vec![ModuleDefinitionAppendix { + module_identifier: "shared".to_string(), + definitions: vec![definition("flow")], + }]; + + append_definitions_to_matching_modules(&mut modules, appendices); + + assert_eq!(modules[0].definitions.len(), 1); + assert_eq!(modules[1].definitions.len(), 0); + assert_eq!(modules[2].definitions.len(), 1); + } + + #[test] + fn appends_multiple_matching_appendices() { + let mut modules = vec![module("shared")]; + let appendices = vec![ + ModuleDefinitionAppendix { + module_identifier: "shared".to_string(), + definitions: vec![definition("flow-a")], + }, + ModuleDefinitionAppendix { + module_identifier: "shared".to_string(), + definitions: vec![definition("flow-b")], + }, + ModuleDefinitionAppendix { + module_identifier: "other".to_string(), + definitions: vec![definition("flow-c")], + }, + ]; + + append_definitions_to_matching_modules(&mut modules, appendices); + + assert_eq!(modules[0].definitions.len(), 2); + assert_eq!( + modules[0].definitions[0].flow_type_identifier, + vec!["flow-a".to_string()] + ); + assert_eq!( + modules[0].definitions[1].flow_type_identifier, + vec!["flow-b".to_string()] + ); + } +}