use {
crate::{
fh::{ComponentInformation, ComponentType, Level},
module::{Module, ModulePtr, Modules, RuntimeInformation},
LewpError,
LewpErrorKind,
},
lewp_html::Nodes,
std::rc::Rc,
};
pub trait SubModule: Module {
fn submodules(&self) -> &Modules;
fn submodules_mut(&mut self) -> &mut Modules;
fn append_module(&mut self, module: ModulePtr) -> Result<(), LewpError> {
if self.id() == module.borrow().id() {
return Err(LewpError {
kind: LewpErrorKind::LoopDetection,
message: format!(
"Circular reference found in module with id '{}'.",
self.id()
),
source_component: self.component_information(),
});
}
self.submodules_mut().push(module);
Ok(())
}
fn render_submodules(&self, parent_module_view: &mut Nodes) {
for module in self.submodules() {
parent_module_view.append(&mut module.borrow().render());
}
}
fn render_submodule(
&self,
idx: usize,
parent_module_view: &mut Nodes,
) -> Result<(), LewpError> {
let module = match self.submodules().get(idx) {
Some(m) => m.borrow(),
None => {
return Err(LewpError {
kind: LewpErrorKind::Render,
message: format!(
"Could not find module with index {}.",
idx
),
source_component: self.component_information(),
});
}
};
parent_module_view.append(&mut module.render());
Ok(())
}
fn render_submodule_id(
&self,
id: &str,
parent_module_view: &mut Nodes,
) -> Result<(), LewpError> {
for module in self.submodules() {
let module = module.borrow();
if module.id() != id {
continue;
}
parent_module_view.append(&mut module.render());
return Ok(());
}
Err(LewpError {
kind: LewpErrorKind::Render,
message:
"Module could not be found in the submodules during rendering."
.to_string(),
source_component: self.component_information(),
})
}
fn render_submodule_id_all(
&self,
id: &str,
parent_module_view: &mut Nodes,
) -> Result<(), LewpError> {
for module in self.submodules() {
let module = module.borrow();
if module.id() != id {
continue;
}
parent_module_view.append(&mut module.render());
}
Ok(())
}
fn run_submodules(
&mut self,
runtime_information: Rc<RuntimeInformation>,
) -> Result<(), LewpError> {
for module in self.submodules() {
let mut module = module.borrow_mut();
module.run(runtime_information.clone())?;
runtime_information.increase_execution_count(module.id());
}
Ok(())
}
fn run_submodule(&mut self, idx: usize) -> Result<(), LewpError> {
let submodules = self.submodules();
let mut module = match submodules.get(idx) {
Some(m) => m.borrow_mut(),
None => {
return Err(LewpError {
kind: LewpErrorKind::Runtime,
message: format!(
"Could not run submodule with index {}",
idx
),
source_component: self.component_information(),
});
}
};
module.run(Rc::new(RuntimeInformation::new()))?;
Ok(())
}
fn run_submodule_id(&mut self, id: &str) -> Result<(), LewpError> {
for module in self.submodules() {
let mut module = module.borrow_mut();
if module.id() != id {
continue;
}
module.run(Rc::new(RuntimeInformation::new()))?;
return Ok(());
}
Err(LewpError {
kind: LewpErrorKind::ModuleNotFound,
message: "Could not find module in submodules register."
.to_string(),
source_component: self.component_information(),
})
}
fn run_submodule_id_all(&mut self, id: &str) -> Result<(), LewpError> {
for module in self.submodules() {
let mut module = module.borrow_mut();
if module.id() != id {
continue;
}
module.run(Rc::new(RuntimeInformation::new()))?;
}
Ok(())
}
fn component_information(&self) -> Rc<ComponentInformation> {
Rc::new(ComponentInformation {
id: self.id().to_string(),
level: Level::Module,
kind: ComponentType::Module,
})
}
}