blvm_sdk/module/
bootstrap.rs1use std::collections::HashMap;
7use std::path::{Path, PathBuf};
8
9#[cfg(feature = "node")]
12pub trait ModuleConfig: Default {
13 fn load_config(path: impl AsRef<Path>) -> Result<Self, anyhow::Error>
14 where
15 Self: Sized;
16 fn config_map(&self) -> HashMap<String, String>;
18}
19
20#[macro_export]
22macro_rules! impl_module_config {
23 ($config:ty) => {
24 impl $crate::module::ModuleConfig for $config {
25 fn load_config(
26 path: impl std::convert::AsRef<std::path::Path>,
27 ) -> Result<Self, anyhow::Error> {
28 <$config>::load(path)
29 }
30 fn config_map(&self) -> std::collections::HashMap<String, String> {
31 self.to_context_map()
32 }
33 }
34 };
35}
36
37#[derive(Clone, Debug)]
42pub struct ModuleBootstrap {
43 pub module_id: String,
44 pub socket_path: PathBuf,
45 pub data_dir: PathBuf,
46}
47
48impl ModuleBootstrap {
49 pub fn from_env() -> Result<Self, std::env::VarError> {
53 Ok(Self {
54 module_id: std::env::var("MODULE_ID")?,
55 socket_path: PathBuf::from(std::env::var("SOCKET_PATH")?),
56 data_dir: PathBuf::from(std::env::var("DATA_DIR")?),
57 })
58 }
59
60 pub fn from_env_or_defaults(
62 module_id: impl Into<String>,
63 socket_path: impl Into<PathBuf>,
64 data_dir: impl Into<PathBuf>,
65 ) -> Self {
66 Self::from_env().unwrap_or_else(|_| Self {
67 module_id: module_id.into(),
68 socket_path: socket_path.into(),
69 data_dir: data_dir.into(),
70 })
71 }
72
73 pub fn for_module(module_name: &str) -> Self {
77 Self::from_env().unwrap_or_else(|_| Self {
78 module_id: module_name.to_string(),
79 socket_path: PathBuf::from(format!("data/modules/{module_name}.sock")),
80 data_dir: PathBuf::from(format!("data/modules/{module_name}")),
81 })
82 }
83
84 #[cfg(feature = "node")]
86 pub fn init_module(module_name: &str) -> Self {
87 blvm_node::utils::init_module_logging(module_name.replace('-', "_").as_str(), None);
88 let bootstrap = Self::for_module(module_name);
89 std::env::set_var("DATA_DIR", bootstrap.data_dir.to_string_lossy().as_ref());
90 tracing::info!(
91 "{} starting... (module_id: {}, socket: {:?})",
92 module_name,
93 bootstrap.module_id,
94 bootstrap.socket_path
95 );
96 bootstrap
97 }
98
99 #[cfg(feature = "node")]
101 pub fn context(
102 &self,
103 data_dir: &Path,
104 config: HashMap<String, String>,
105 ) -> blvm_node::module::traits::ModuleContext {
106 blvm_node::module::traits::ModuleContext {
107 module_id: self.module_id.clone(),
108 socket_path: self.socket_path.to_string_lossy().to_string(),
109 data_dir: data_dir.to_string_lossy().to_string(),
110 config,
111 }
112 }
113
114 #[cfg(feature = "node")]
116 pub fn context_with_config<C: ModuleConfig>(
117 &self,
118 data_dir: &Path,
119 ) -> (blvm_node::module::traits::ModuleContext, C) {
120 let config = C::load_config(data_dir.join("config.toml")).unwrap_or_default();
121 let ctx = self.context(data_dir, config.config_map());
122 (ctx, config)
123 }
124}