use std::sync::{
Arc,
OnceLock,
};
use parking_lot::RwLock;
use qubit_spi::ServiceProvider;
use crate::{
FileResource,
FileSystem,
FileSystemProvider,
FileSystemRegistry,
FileSystemSpec,
FsResult,
FsUri,
};
static GLOBAL_REGISTRY: OnceLock<RwLock<FileSystemRegistry>> = OnceLock::new();
pub enum FileSystems {}
impl FileSystems {
fn registry() -> &'static RwLock<FileSystemRegistry> {
GLOBAL_REGISTRY.get_or_init(|| RwLock::new(FileSystemRegistry::new()))
}
pub fn register<P>(provider: P) -> FsResult<()>
where
P: ServiceProvider<FileSystemSpec> + 'static,
{
let mut registry = Self::registry().write();
registry.register(provider)
}
pub fn register_shared(provider: Arc<FileSystemProvider>) -> FsResult<()> {
let mut registry = Self::registry().write();
registry.register_shared(provider)
}
pub fn fs(uri: &str) -> FsResult<Arc<dyn FileSystem>> {
let uri = FsUri::parse(uri)?;
Self::fs_for_uri(&uri)
}
pub fn fs_for_uri(uri: &FsUri) -> FsResult<Arc<dyn FileSystem>> {
let registry = Self::registry().read();
registry.fs(uri)
}
pub fn fs_for_scheme(scheme: &str) -> FsResult<Arc<dyn FileSystem>> {
let uri = FsUri::parse(&format!("{scheme}:///"))?;
Self::fs_for_uri(&uri)
}
pub fn resource(uri: &str) -> FsResult<FileResource> {
let uri = FsUri::parse(uri)?;
Self::resource_for_uri(&uri)
}
pub fn resource_for_uri(uri: &FsUri) -> FsResult<FileResource> {
let registry = Self::registry().read();
registry.resource(uri)
}
#[must_use]
pub fn provider_names() -> Vec<String> {
let registry = Self::registry().read();
registry.provider_names().into_iter().map(str::to_owned).collect()
}
}