serenade_kernel/application.rs
1//! Default application wrapper around [`Kernel`].
2
3use crate::{BundleInterface, Environment, Kernel, KernelError};
4
5/// Host that owns a [`Kernel`].
6pub trait Application {
7 /// Shared kernel access.
8 fn kernel(&self) -> &Kernel;
9
10 /// Boots the kernel (compile then boot).
11 ///
12 /// # Errors
13 ///
14 /// Propagates [`Kernel::boot`] errors.
15 fn boot(&mut self) -> Result<(), KernelError>;
16
17 /// Shuts the kernel down.
18 ///
19 /// # Errors
20 ///
21 /// Propagates [`Kernel::shutdown`] errors.
22 fn shutdown(&mut self) -> Result<(), KernelError>;
23}
24
25/// Default application: a kernel plus ordered bundle registration.
26///
27/// # Examples
28///
29/// ```
30/// use serenade_kernel::{App, Application, BundleInterface, Environment, KernelPhase};
31///
32/// struct Demo;
33///
34/// impl BundleInterface for Demo {
35/// fn name(&self) -> &'static str {
36/// "demo"
37/// }
38/// }
39///
40/// let mut app = App::new(Environment::Dev);
41/// app.register_bundle(Demo).expect("register");
42/// app.boot().expect("boot");
43/// assert_eq!(app.kernel().bundle_names(), vec!["demo"]);
44/// assert_eq!(app.kernel().phase(), KernelPhase::Booted);
45/// ```
46pub struct App {
47 kernel: Kernel,
48}
49
50impl App {
51 /// Creates an application in [`crate::KernelPhase::Created`].
52 #[must_use]
53 pub fn new(environment: Environment) -> Self {
54 Self {
55 kernel: Kernel::new(environment),
56 }
57 }
58
59 /// Overrides debug on the inner kernel. Call before [`Application::boot`].
60 #[must_use]
61 pub fn with_debug(mut self, debug: bool) -> Self {
62 self.kernel = self.kernel.with_debug(debug);
63 self
64 }
65
66 /// Registers a bundle on the inner kernel.
67 ///
68 /// # Errors
69 ///
70 /// Propagates [`Kernel::register_bundle`] errors.
71 pub fn register_bundle(
72 &mut self,
73 bundle: impl BundleInterface + 'static,
74 ) -> Result<(), KernelError> {
75 self.kernel.register_bundle(bundle)
76 }
77}
78
79impl Application for App {
80 fn kernel(&self) -> &Kernel {
81 &self.kernel
82 }
83
84 fn boot(&mut self) -> Result<(), KernelError> {
85 self.kernel.boot()
86 }
87
88 fn shutdown(&mut self) -> Result<(), KernelError> {
89 self.kernel.shutdown()
90 }
91}