use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use super::error::ZebFsError;
use super::local::LocalZebFs;
pub const BACKEND_ZEBFS: &str = "zebfs";
pub const FILE_BACKENDS: &[&str] = &[BACKEND_ZEBFS];
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FileBackend {
#[default]
Zebfs,
}
impl FileBackend {
pub fn as_str(self) -> &'static str {
match self {
Self::Zebfs => BACKEND_ZEBFS,
}
}
pub fn label(self) -> &'static str {
match self {
Self::Zebfs => "Local disk",
}
}
pub fn parse(value: &str) -> Result<Self, ZebFsError> {
match value {
BACKEND_ZEBFS => Ok(Self::Zebfs),
other => Err(ZebFsError::new(
"ZEBFS_UNKNOWN_BACKEND",
unknown_backend_message(other),
)),
}
}
pub fn resolve(declared: Option<&str>) -> Result<Self, ZebFsError> {
match declared {
Some(value) => Self::parse(value),
None => Ok(Self::default()),
}
}
}
pub fn unknown_backend_message(value: &str) -> String {
format!(
"'{value}' is not a file storage backend this build provides; accepted: {}",
FILE_BACKENDS.join(", ")
)
}
pub fn open(backend: FileBackend, files_dir: PathBuf) -> LocalZebFs {
match backend {
FileBackend::Zebfs => LocalZebFs::new(files_dir),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_declared_word_is_the_word_a_file_ref_carries() {
assert_eq!(
FileBackend::default().as_str(),
crate::pipeline::nodes::shared::file_ref::BACKEND_ZEBFS
);
}
#[test]
fn an_absent_declaration_resolves_to_the_local_backend() {
assert_eq!(FileBackend::resolve(None).unwrap(), FileBackend::Zebfs);
assert_eq!(FileBackend::default().as_str(), "zebfs");
}
#[test]
fn a_declared_local_backend_resolves_to_the_same_implementation() {
let files_dir = PathBuf::from("/tmp/zebflow-backend-test/files");
let declared = open(
FileBackend::resolve(Some("zebfs")).unwrap(),
files_dir.clone(),
);
let absent = open(FileBackend::resolve(None).unwrap(), files_dir.clone());
assert_eq!(declared.root(), absent.root());
assert_eq!(declared.root(), files_dir.as_path());
}
#[test]
fn an_unknown_backend_is_refused_by_name_with_the_accepted_list() {
let err = FileBackend::parse("s3").unwrap_err();
assert_eq!(err.code, "ZEBFS_UNKNOWN_BACKEND");
assert!(err.message.contains("'s3'"), "{}", err.message);
assert!(err.message.contains("accepted: zebfs"), "{}", err.message);
}
}