1use sofie_db::worker::Worker;
2use sofie_db::{Db, File, Migrations};
3
4#[cfg(feature = "engine")]
5use crate::screens::Form;
6use crate::{App, RouteName};
7
8pub type Mount = fn(App, &'static str) -> App;
9
10#[derive(Clone, Copy)]
13pub struct Module {
14 pub name: &'static str,
16 pub tier: Tier,
17 pub context: Option<&'static str>,
19 pub settings: &'static [Setting],
20 pub migrations: Option<Migrations>,
21 pub route_names: &'static [RouteName],
23 pub screens: &'static [(&'static str, File)],
25 #[cfg(feature = "engine")]
26 pub forms: &'static [Form],
27 pub areas: &'static [Mount],
28 pub jobs: fn(Worker) -> Worker,
29}
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum Tier {
34 Experience,
35 Core,
36 Platform,
37}
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq)]
40pub struct Setting {
41 pub name: &'static str,
42 pub default: SettingValue,
43}
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq)]
46pub enum SettingValue {
47 Switch(bool),
48 Number(i64),
49 Text(&'static str),
50}
51
52impl Module {
53 #[must_use]
55 pub const fn new(name: &'static str) -> Self {
56 Self {
57 name,
58 tier: Tier::Platform,
59 context: None,
60 settings: &[],
61 migrations: None,
62 route_names: &[],
63 screens: &[],
64 #[cfg(feature = "engine")]
65 forms: &[],
66 areas: &[],
67 jobs: no_jobs,
68 }
69 }
70}
71
72fn no_jobs(worker: Worker) -> Worker {
73 worker
74}
75
76#[must_use]
77pub fn migrations(modules: &[Module]) -> Vec<Migrations> {
78 modules
79 .iter()
80 .filter_map(|module| module.migrations)
81 .collect()
82}
83
84#[must_use]
85pub fn worker(db: Db, modules: &[Module]) -> Worker {
86 modules
87 .iter()
88 .fold(Worker::new(db), |worker, module| (module.jobs)(worker))
89}
90
91impl App {
92 #[must_use]
93 pub fn modules(mut self, modules: &[Module]) -> Self {
94 for module in modules {
95 self.names.extend_from_slice(module.route_names);
96 }
97 modules.iter().fold(self, |app, module| {
98 module
99 .areas
100 .iter()
101 .fold(app, |app, mount| mount(app, module.name))
102 })
103 }
104}