use crate::platform::PlatformStorage;
use anyhow::Result;
use noosphere_core::data::Did;
use noosphere_storage::StorageConfig;
use std::{
fmt::Display,
path::{Path, PathBuf},
};
use url::Url;
#[cfg(doc)]
use noosphere_storage::Storage;
#[cfg(feature = "ipfs-storage")]
use noosphere_ipfs::{GatewayClient, IpfsStorage};
pub enum StorageLayout {
Scoped(PathBuf, Did),
Unscoped(PathBuf),
}
impl Display for StorageLayout {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let path = PathBuf::from(self);
write!(f, "{}", path.to_string_lossy())
}
}
impl From<&StorageLayout> for PathBuf {
fn from(layout: &StorageLayout) -> Self {
match layout {
StorageLayout::Scoped(path, scope) => get_scoped_path(path, scope),
StorageLayout::Unscoped(path) => path.join(".sphere/storage"),
}
}
}
impl From<StorageLayout> for PathBuf {
fn from(layout: StorageLayout) -> Self {
PathBuf::from(&layout)
}
}
fn get_scoped_path(path: &Path, scope: &Did) -> PathBuf {
#[cfg(not(windows))]
let path_buf = path.join(scope.as_str());
#[cfg(windows)]
let path_buf = path.join(scope.as_str().replace(":", "_"));
path_buf
}
pub async fn create_platform_storage(
layout: StorageLayout,
#[allow(unused)] ipfs_gateway_url: Option<Url>,
#[allow(unused)] storage_config: Option<StorageConfig>,
) -> Result<PlatformStorage> {
#[cfg(any(sled, rocksdb))]
let storage = {
use noosphere_storage::ConfigurableStorage;
let path: PathBuf = layout.into();
crate::platform::PrimitiveStorage::open_with_config(
&path,
storage_config.unwrap_or_default(),
)
.await?
};
#[cfg(wasm)]
let storage = noosphere_storage::IndexedDbStorage::new(&layout.to_string()).await?;
#[cfg(ipfs_storage)]
let storage = {
let maybe_client = ipfs_gateway_url.map(|url| GatewayClient::new(url));
IpfsStorage::new(storage, maybe_client)
};
debug!("Created platform storage: {:#?}", storage);
Ok(storage)
}