marine/config/
raw_marine_config.rs1use crate::MarineError;
18use crate::MarineResult;
19
20use bytesize::ByteSize;
21use serde_derive::Serialize;
22use serde_derive::Deserialize;
23use serde_with::serde_as;
24use serde_with::skip_serializing_none;
25
26use std::path::Path;
27use std::path::PathBuf;
28
29#[derive(Deserialize, Serialize, Debug, Clone, Default)]
61pub struct TomlMarineConfig {
62 pub modules_dir: Option<PathBuf>,
63 pub total_memory_limit: MemoryLimit,
64 #[serde(skip_serializing_if = "Vec::is_empty")]
65 pub module: Vec<TomlMarineNamedModuleConfig>,
66 pub default: Option<TomlMarineModuleConfig>,
67 #[serde(skip)]
68 pub base_path: PathBuf,
69}
70
71impl TomlMarineConfig {
72 pub fn load<P: AsRef<Path>>(path: P) -> MarineResult<Self> {
74 let path = PathBuf::from(path.as_ref()).canonicalize().map_err(|e| {
75 MarineError::IOError(format!(
76 "failed to canonicalize path {}: {}",
77 path.as_ref().display(),
78 e
79 ))
80 })?;
81
82 let file_content = std::fs::read(&path).map_err(|e| {
83 MarineError::IOError(format!("failed to load {}: {}", path.display(), e))
84 })?;
85
86 let mut config: TomlMarineConfig = toml::from_slice(&file_content)?;
87
88 let default_base_path = Path::new("/");
89 config.base_path = path
90 .canonicalize()
91 .map_err(|e| {
92 MarineError::IOError(format!(
93 "Failed to canonicalize config path {}: {}",
94 path.display(),
95 e
96 ))
97 })?
98 .parent()
99 .unwrap_or(default_base_path)
100 .to_path_buf();
101
102 Ok(config)
103 }
104}
105
106#[derive(Deserialize, Serialize, Debug, Clone, Default)]
107pub struct TomlMarineNamedModuleConfig {
108 pub name: String,
109 #[serde(default)]
110 pub load_from: Option<PathBuf>,
111 #[serde(default)]
112 pub file_name: Option<String>,
113 #[serde(flatten)]
114 pub config: TomlMarineModuleConfig,
115}
116
117#[skip_serializing_none]
118#[derive(Deserialize, Serialize, Debug, Clone, Default)]
119pub struct TomlMarineModuleConfig {
120 pub logger_enabled: Option<bool>,
121 pub logging_mask: Option<i32>,
122 pub wasi: Option<TomlWASIConfig>,
123 pub mounted_binaries: Option<toml::value::Table>,
124}
125
126#[derive(Deserialize, Serialize, Debug, Clone, Default)]
127pub struct TomlWASIConfig {
128 pub envs: Option<toml::value::Table>,
129 pub mapped_dirs: Option<toml::value::Table>,
130}
131
132#[derive(Serialize, Deserialize, Debug, Clone, Default)]
133#[serde_as]
134pub enum MemoryLimit {
135 #[default]
136 #[serde(alias = "infinity")]
137 Infinity,
138 #[serde(untagged)]
139 Value(#[serde_as(as = "Option<DisplayFromStr>")] ByteSize),
140}
141
142#[cfg(test)]
143mod tests {
144 use super::TomlMarineNamedModuleConfig;
145 use super::TomlMarineModuleConfig;
146 use super::TomlWASIConfig;
147
148 #[test]
149 fn serialize_marine_named_module_config() {
150 let mut mounted_binaries = toml::value::Table::new();
151 mounted_binaries.insert(
152 "curl".to_string(),
153 toml::Value::String("/usr/local/bin/curl".to_string()),
154 );
155
156 let config = TomlMarineNamedModuleConfig {
157 name: "name".to_string(),
158 file_name: Some("file_name".to_string()),
159 load_from: <_>::default(),
160 config: TomlMarineModuleConfig {
161 logger_enabled: Some(false),
162 logging_mask: Some(1),
163 wasi: Some(TomlWASIConfig {
164 envs: None,
165 mapped_dirs: None,
166 }),
167 mounted_binaries: Some(mounted_binaries),
168 },
169 };
170
171 assert!(toml::to_string(&config).is_ok())
172 }
173}