use std::path::PathBuf;
use std::sync::Arc;
use anyhow::{Result, bail};
use common::future::BoxFut;
use surrealdb_cnf as cnf;
use crate::CommunityComposer;
use crate::buc::store::ObjectStore;
#[cfg(not(target_arch = "wasm32"))]
use crate::buc::store::file::FileStore;
use crate::buc::store::memory::MemoryStore;
mod controller;
mod error;
pub mod manager;
pub mod store;
pub(crate) use controller::BucketController;
pub use controller::BucketOperation;
pub(crate) use error::Error;
#[derive(Clone, Debug, Default)]
pub struct Config {
bucket_list: Vec<PathBuf>,
only_global: bool,
global_bucket: Option<String>,
}
impl cnf::Config for Config {
fn parse(&mut self, map: &cnf::ConfigMap) {
map.parse_key_with("bucket_folder_allowlist", &mut self.bucket_list, |x| {
Some(cnf::extract_allowed_paths(x, false, "bucket folder"))
})
.parse_key_with("global_bucket", &mut self.global_bucket, |x| Some(Some(x.to_owned())))
.parse_key("global_bucket_enforced", &mut self.only_global);
}
}
#[cfg(test)]
impl Config {
pub(crate) fn for_test(bucket_list: Vec<PathBuf>) -> Self {
Self {
bucket_list,
..Self::default()
}
}
}
pub trait BucketStoreProviderRequirements: Send + Sync + 'static {}
pub trait BucketStoreProvider: BucketStoreProviderRequirements {
fn connect<'a>(
&self,
url: &'a str,
global: bool,
readonly: bool,
config: Config,
) -> BoxFut<'a, Result<Arc<dyn ObjectStore>>>;
}
impl BucketStoreProviderRequirements for CommunityComposer {}
impl BucketStoreProvider for CommunityComposer {
fn connect<'a>(
&self,
url: &'a str,
_global: bool,
_readonly: bool,
config: Config,
) -> BoxFut<'a, Result<Arc<dyn ObjectStore>>> {
Box::pin(async {
#[cfg(target_arch = "wasm32")]
let _ = config;
if MemoryStore::parse_url(url) {
return Ok(Arc::new(MemoryStore::new()) as Arc<dyn ObjectStore>);
}
#[cfg(not(target_arch = "wasm32"))]
if let Some(opts) = FileStore::parse_url(url, &config).await? {
return Ok(Arc::new(FileStore::new(opts, config)) as Arc<dyn ObjectStore>);
}
#[cfg(not(target_arch = "wasm32"))]
if let Some(store) = crate::buc::store::cloud::connect(url)? {
return Ok(store);
}
bail!(Error::UnsupportedBackend)
})
}
}