jupiter/builder.rs
1//! Provides a builder which can be used to setup and initialize the framework.
2//!
3//! This can be used to crate and setup central parts of the framework. As Jupiter provides some
4//! optional modules, a builder permits to selectively enable or disable them.
5//!
6//! # Example
7//! Setting up the framework with all features enabled:
8//! ```no_run
9//! # use jupiter::builder::Builder;
10//! # use jupiter::server::Server;
11//! #[tokio::main]
12//! async fn main() {
13//! // Enable all features and build the platform...
14//! let platform = Builder::new().enable_all().build().await;
15//!
16//! // Register custom functions here...
17//!
18//! // Start the main event loop of the server...
19//! platform.require::<Server>().event_loop().await;
20//! }
21//! ```
22use crate::platform::Platform;
23use crate::server::Server;
24use crate::{init_logging, JUPITER_REVISION, JUPITER_VERSION};
25use std::sync::Arc;
26
27/// Initializes the framework by creating and initializing all core components.
28///
29/// As Jupiter provides a bunch of components of which some are optional, the actual setup
30/// can be configured here.
31///
32/// # Example
33/// Setting up the framework with all features enabled:
34/// ```no_run
35/// # use jupiter::builder::Builder;
36/// # use jupiter::server::Server;
37/// #[tokio::main]
38/// async fn main() {
39/// // Enable all features and build the platform...
40/// let platform = Builder::new().enable_all().build().await;
41///
42/// // Register custom functions here...
43///
44/// // Start the main event loop of the server...
45/// platform.require::<Server>().event_loop().await;
46/// }
47/// ```
48#[derive(Default)]
49pub struct Builder {
50 setup_logging: bool,
51 enable_signals: bool,
52 core_commands: bool,
53 setup_config: bool,
54 setup_commands: bool,
55 setup_server: bool,
56 version_info: String,
57 revision_info: String,
58}
59
60impl Builder {
61 /// Creates a new builder.
62 pub fn new() -> Self {
63 Builder {
64 setup_logging: false,
65 enable_signals: false,
66 core_commands: false,
67 setup_config: false,
68 setup_commands: false,
69 setup_server: false,
70 version_info: "-".to_string(),
71 revision_info: "-".to_string(),
72 }
73 }
74
75 /// Enables all features.
76 ///
77 /// Note that using this method (and then maybe disabling selected components) is quote
78 /// convenient, but be aware that new components which might be added in a library update
79 /// will then also be enabled by default. This might or might not be the expected behaviour.
80 pub fn enable_all(mut self) -> Self {
81 self.setup_logging = true;
82 self.enable_signals = true;
83 self.core_commands = true;
84 self.setup_config = true;
85 self.setup_commands = true;
86 self.setup_server = true;
87
88 self
89 }
90
91 /// Enables the automatic setup of the logging system.
92 ///
93 /// Using this, we properly initialize **simplelog** to log to stdout. As we intend Jupiter
94 /// to be run in docker containers, this is all that is needed for proper logging. The date
95 /// format being used is digestible by established tools like **greylog**.
96 pub fn enable_logging(mut self) -> Self {
97 self.setup_logging = true;
98 self
99 }
100
101 /// Disables the automatic setup of the logging system after [enable_all()](Builder::enable_all)
102 /// has been used.
103 pub fn disable_logging(mut self) -> Self {
104 self.setup_logging = false;
105 self
106 }
107
108 /// Installs a signal listener which terminates the framework once **CTRL-C** or **SIGHUP**
109 /// is received.
110 ///
111 /// For more details see: [signals](crate::signals)
112 pub fn enable_signals(mut self) -> Self {
113 self.enable_signals = true;
114 self
115 }
116
117 /// Disables installing the signal listener after [enable_all()](Builder::enable_all)
118 /// has been used.
119 pub fn disable_signals(mut self) -> Self {
120 self.enable_signals = false;
121 self
122 }
123
124 /// Installs a bunch of health and maintenance commands.
125 ///
126 /// For more details see: [core](crate::core)
127 pub fn enable_core_commands(mut self) -> Self {
128 self.core_commands = true;
129 self
130 }
131
132 /// Disables installing the **core** commands after [enable_all()](Builder::enable_all)
133 /// has been used.
134 pub fn disable_core_commands(mut self) -> Self {
135 self.core_commands = false;
136 self
137 }
138
139 /// Installs [config::Config](jupiter::config::Config) and loads the **settings.yml**.
140 ///
141 /// For more details see: [config](crate::config)
142 pub fn enable_config(mut self) -> Self {
143 self.setup_config = true;
144 self
145 }
146
147 /// Disables setting up a **Config** instance after [enable_all()](Builder::enable_all)
148 /// has been used.
149 pub fn disable_config(mut self) -> Self {
150 self.setup_config = false;
151 self
152 }
153
154 /// Creates and installs a [CommandDictionary](crate::commands::CommandDictionary).
155 ///
156 /// For more details see: [Commands](crate::commands)
157 pub fn enable_commands(mut self) -> Self {
158 self.setup_commands = true;
159 self
160 }
161
162 /// Disables setting up a **Commands** instance after [enable_all()](Builder::enable_all)
163 /// has been used.
164 pub fn disable_commands(mut self) -> Self {
165 self.setup_commands = false;
166 self
167 }
168
169 /// Creates and installs a [Server](crate::server::Server) instance.
170 ///
171 /// For more details see: [server](crate::server::Server). Note that still, the main event loop
172 /// has to be invoked manually via: `platform.require::<Server>().event_loop().await`.
173 pub fn enable_server(mut self) -> Self {
174 self.setup_server = true;
175 self
176 }
177
178 /// Disables setting up a **Server** instance after [enable_all()](Builder::enable_all)
179 /// has been used.
180 pub fn disable_server(mut self) -> Self {
181 self.setup_server = false;
182 self
183 }
184
185 /// Specifies the version of the application to show when calling `SYS.VERSION`.
186 pub fn with_version(mut self, version: impl AsRef<str>, revision: impl AsRef<str>) -> Self {
187 self.version_info = version.as_ref().to_string();
188 self.revision_info = revision.as_ref().to_string();
189
190 self
191 }
192
193 /// Builds the [Platform](jupiter::platform::Platform) registry with all the enabled components
194 /// being registered.
195 pub async fn build(self) -> Arc<Platform> {
196 let platform = Platform::new();
197
198 if self.setup_logging {
199 init_logging();
200 }
201
202 log::info!(
203 "||. JUPITER (v {} - rev {}) running on {} core(s) in {} CPU(s)",
204 JUPITER_VERSION,
205 JUPITER_REVISION,
206 num_cpus::get(),
207 num_cpus::get_physical()
208 );
209
210 if self.enable_signals {
211 crate::signals::install(platform.clone());
212 }
213
214 if self.setup_config {
215 let _ = crate::config::install(platform.clone(), true).await;
216 }
217
218 if self.setup_server {
219 let _ = Server::install(&platform);
220 }
221
222 if self.setup_commands {
223 let _ = crate::commands::CommandDictionary::install(&platform);
224
225 if self.core_commands {
226 crate::core::install(platform.clone(), self.version_info, self.revision_info);
227 }
228 }
229
230 platform
231 }
232}