1use crate::{BoxedControllerFn, BoxedModule};
2
3pub trait Module {
4 type Context;
5 type ControllerContext;
6 type ControllerReturn;
7
8 fn details(
9 &self,
10 ctx: &mut Self::Context,
11 ) -> ModuleDetails<Self::Context, Self::ControllerContext, Self::ControllerReturn>;
12}
13
14pub struct ModuleDetails<Ctx, ConCtx, ConRet> {
15 pub imports: Vec<BoxedModule<Ctx, ConCtx, ConRet>>,
16 pub controllers: Vec<BoxedControllerFn<ConCtx, ConRet>>,
17}
18
19#[allow(dead_code)]
20pub(crate) fn resolve_module<Ctx, ConCtx, ConRet>(
21 module: &dyn Module<Context = Ctx, ControllerContext = ConCtx, ControllerReturn = ConRet>,
22 context: &mut Ctx,
23) -> Vec<BoxedControllerFn<ConCtx, ConRet>> {
24 let mut controllers = vec![];
25 configure_module_recursive(module, context, &mut controllers);
26
27 controllers
28}
29
30#[allow(dead_code)]
31fn configure_module_recursive<Ctx, ConCtx, ConRet>(
32 module: &dyn Module<Context = Ctx, ControllerContext = ConCtx, ControllerReturn = ConRet>,
33 context: &mut Ctx,
34 controllers: &mut Vec<BoxedControllerFn<ConCtx, ConRet>>,
35) {
36 let details = module.details(context);
37 controllers.extend(details.controllers);
38
39 for imported_module in details.imports {
40 configure_module_recursive(&*imported_module, context, controllers);
41 }
42}