GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: MIT
4
5use crate::{imports, Plugin, PluginReporter, PluginRun, Server};
6use std::sync::{Arc, OnceLock};
7
8type DynServer = Arc<Server>;
9type DynPlugin = Arc<dyn Plugin + Send + Sync>;
10type DynPluginReporter = Arc<dyn PluginReporter + Send + Sync>;
11
12static INSTANCE: OnceLock<DynServer> = OnceLock::new();
13static PLUGIN: OnceLock<DynPlugin> = OnceLock::new();
14static PLUGIN_REPORTER: OnceLock<DynPluginReporter> = OnceLock::new();
15
16pub fn register<T, F>(run: Vec<PluginRun>, plugin_factory: F)
17where
18 T: Plugin + Send + Sync,
19 F: FnOnce(DynServer) -> T,
20{
21 let _ = INSTANCE.set(Arc::new(Server::new(run)));
22 let static_server = INSTANCE.get().unwrap();
23 let _ = PLUGIN.set(Arc::new(plugin_factory(static_server.clone())));
24}
25
26pub fn register_reporter<T, F>(run: Vec<PluginRun>, plugin_factory: F)
27where
28 T: PluginReporter + Send + Sync,
29 F: FnOnce(DynServer) -> T,
30{
31 let _ = INSTANCE.set(Arc::new(Server::new(run)));
32 let static_server = INSTANCE.get().unwrap();
33 let _ = PLUGIN_REPORTER.set(Arc::new(plugin_factory(static_server.clone())));
34}
35
36pub fn get() -> DynServer {
37 INSTANCE
38 .get()
39 .expect("Server has not been initialized. Call Server::init() first.")
40 .clone()
41}
42
43pub fn with_plugin<F>(f: F)
44where
45 F: FnOnce(DynPlugin) -> Result<(), String>,
46{
47 if let Some(plugin) = PLUGIN.get() {
48 let _ =
49 f(plugin.clone()).map_err(|err| imports::log_error(String::from("unknown error"), err));
50 } else if let Some(plugin) = PLUGIN_REPORTER.get() {
51 let _ =
52 f(plugin.clone()).map_err(|err| imports::log_error(String::from("unknown error"), err));
53 } else {
54 imports::log_error(
55 String::from("Plugin not initialized after server was created"),
56 String::from("Fatal error"),
57 );
58 }
59}
60
61pub fn with_plugin_reporter<F>(f: F)
62where
63 F: FnOnce(DynPluginReporter) -> Result<(), String>,
64{
65 if let Some(plugin) = PLUGIN_REPORTER.get() {
66 let _ =
67 f(plugin.clone()).map_err(|err| imports::log_error(String::from("unknown error"), err));
68 } //no else the plugin is not a reporter
69}