use super::RawFileSystem;
use crate::{algo::Algorithm, db::Database, Result, sodium};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum FileEncryption {
Aes256Gcm,
ChaCha20Poly1305,
XChaCha20Poly1305IETF,
XSalsa20,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum OpenDALType {
Memory,
}
#[cfg(feature = "opendal")]
impl OpenDALType {
pub fn build(&self) -> Result<opendal::BlockingOperator> {
use opendal::{services, Operator};
let operator = match self {
Self::Memory => Operator::new(services::Memory::default())?.finish(),
};
Ok(operator.blocking())
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum FileStorage {
Local,
Split {
inner: Box<FileStorage>,
cluster_size: u64,
},
Tracking { inner: Box<FileStorage> },
OpenDAL { ty: OpenDALType, prefix: String },
RocksDB,
}
impl FileStorage {
pub(crate) fn build(
&self,
db: &Arc<Database>,
data_dir: &std::path::Path,
) -> Result<Arc<dyn RawFileSystem + Send + Sync>> {
use crate::fs::raw::*;
Ok(match self {
Self::Local => Arc::new(LocalFileSystem::new(data_dir)),
Self::Split {
inner,
cluster_size,
} => Arc::new(SplitFileSystem::new(
inner.build(db, data_dir)?,
Arc::clone(db),
*cluster_size,
)),
Self::Tracking { inner } => Arc::new(TrackingFileSystem::new(
inner.build(db, data_dir)?,
Arc::clone(db),
)),
#[cfg(feature = "opendal")]
Self::OpenDAL { ty, prefix } => {
let operator = ty.build()?;
Arc::new(OpenDALFileSystem::new(operator, prefix.clone()))
}
#[cfg(not(feature = "opendal"))]
Self::OpenDAL { .. } => {
panic!("OpenDAL is not enabled, please enable it by adding `opendal` feature")
}
Self::RocksDB => Arc::new(RocksDBFileSystem::new(Arc::new(Database::open(
data_dir, None,
)?))),
})
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct Config {
pub version: u32,
pub file_encryption: FileEncryption,
pub block_size: u64,
pub encrypt_db: bool,
pub encrypt_file_name: bool,
pub unix_perms: bool,
pub storage: FileStorage,
pub disable_xattr_gets: bool,
}
impl Default for Config {
fn default() -> Self {
Self {
version: 0,
file_encryption: FileEncryption::Aes256Gcm,
block_size: 4096,
encrypt_db: true,
encrypt_file_name: false,
unix_perms: true,
storage: FileStorage::Local,
disable_xattr_gets: true,
}
}
}
impl Config {
pub const CURRENT_VERSION: u32 = 0;
pub fn to_algorithm(&self) -> Result<Arc<dyn Algorithm + Send + Sync>> {
use crate::algo::*;
Ok(match self.file_encryption {
FileEncryption::Aes256Gcm => {
Arc::new(RingAead::new(&ring::aead::AES_256_GCM, self.block_size)?)
}
FileEncryption::ChaCha20Poly1305 => Arc::new(RingAead::new(
&ring::aead::CHACHA20_POLY1305,
self.block_size,
)?),
FileEncryption::XChaCha20Poly1305IETF => {
Arc::new(SodiumAead::new(&sodium::aead::XCHACHA20_POLY1305_IETF, self.block_size)?)
}
FileEncryption::XSalsa20 => Arc::new(SodiumStream::new(&sodium::stream::XSALSA20, self.block_size)?),
})
}
}