use crate::MarineError;
use crate::MarineResult;
use bytesize::ByteSize;
use serde_derive::Serialize;
use serde_derive::Deserialize;
use serde_with::serde_as;
use serde_with::skip_serializing_none;
use std::path::Path;
use std::path::PathBuf;
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct TomlMarineConfig {
pub modules_dir: Option<PathBuf>,
pub total_memory_limit: MemoryLimit,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub module: Vec<TomlMarineNamedModuleConfig>,
pub default: Option<TomlMarineModuleConfig>,
#[serde(skip)]
pub base_path: PathBuf,
}
impl TomlMarineConfig {
pub fn load<P: AsRef<Path>>(path: P) -> MarineResult<Self> {
let path = PathBuf::from(path.as_ref()).canonicalize().map_err(|e| {
MarineError::IOError(format!(
"failed to canonicalize path {}: {}",
path.as_ref().display(),
e
))
})?;
let file_content = std::fs::read(&path).map_err(|e| {
MarineError::IOError(format!("failed to load {}: {}", path.display(), e))
})?;
let mut config: TomlMarineConfig = toml::from_slice(&file_content)?;
let default_base_path = Path::new("/");
config.base_path = path
.canonicalize()
.map_err(|e| {
MarineError::IOError(format!(
"Failed to canonicalize config path {}: {}",
path.display(),
e
))
})?
.parent()
.unwrap_or(default_base_path)
.to_path_buf();
Ok(config)
}
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct TomlMarineNamedModuleConfig {
pub name: String,
#[serde(default)]
pub load_from: Option<PathBuf>,
#[serde(default)]
pub file_name: Option<String>,
#[serde(flatten)]
pub config: TomlMarineModuleConfig,
}
#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct TomlMarineModuleConfig {
pub logger_enabled: Option<bool>,
pub logging_mask: Option<i32>,
pub wasi: Option<TomlWASIConfig>,
pub mounted_binaries: Option<toml::value::Table>,
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct TomlWASIConfig {
pub preopened_files: Option<Vec<PathBuf>>,
pub envs: Option<toml::value::Table>,
pub mapped_dirs: Option<toml::value::Table>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde_as]
pub enum MemoryLimit {
#[default]
#[serde(alias = "infinity")]
Infinity,
#[serde(untagged)]
Value(#[serde_as(as = "Option<DisplayFromStr>")] ByteSize),
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::TomlMarineNamedModuleConfig;
use super::TomlMarineModuleConfig;
use super::TomlWASIConfig;
#[test]
fn serialize_marine_named_module_config() {
let mut mounted_binaries = toml::value::Table::new();
mounted_binaries.insert(
"curl".to_string(),
toml::Value::String("/usr/local/bin/curl".to_string()),
);
let config = TomlMarineNamedModuleConfig {
name: "name".to_string(),
file_name: Some("file_name".to_string()),
load_from: <_>::default(),
config: TomlMarineModuleConfig {
logger_enabled: Some(false),
logging_mask: Some(1),
wasi: Some(TomlWASIConfig {
preopened_files: Some(vec![PathBuf::from("a")]),
envs: None,
mapped_dirs: None,
}),
mounted_binaries: Some(mounted_binaries),
},
};
assert!(toml::to_string(&config).is_ok())
}
}