use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use void_core::store::{IpfsBackend, IpfsStore, RemoteStore};
use crate::output::CliError;
pub struct ResolvedBackend {
pub ipfs_backend: IpfsBackend,
pub remote: Arc<dyn RemoteStore>,
pub _runtime: Option<tokio::runtime::Runtime>,
}
pub fn resolve_backend(
backend_type: Option<&str>,
kubo_url: &str,
gateway_url: &Option<String>,
void_dir: Option<&Path>,
timeout: Duration,
) -> Result<ResolvedBackend, CliError> {
match backend_type.unwrap_or("daemon") {
"daemon" => {
let dir = void_dir.ok_or_else(|| {
CliError::internal("daemon backend requires a void directory")
})?;
let (remote, rt) = crate::daemon::start_daemon(dir)
.map_err(|e| CliError::internal(e))?;
Ok(ResolvedBackend {
ipfs_backend: IpfsBackend::Kubo { api: "daemon".to_string() },
remote,
_runtime: Some(rt),
})
}
"kubo" => {
let backend = IpfsBackend::Kubo { api: kubo_url.to_string() };
let store = Arc::new(IpfsStore::new(backend.clone(), timeout));
Ok(ResolvedBackend {
ipfs_backend: backend,
remote: store,
_runtime: None,
})
}
"gateway" => {
let url = gateway_url.as_ref().ok_or_else(|| {
CliError::invalid_args("--gateway <url> is required when backend is gateway")
})?;
let backend = IpfsBackend::Gateway { base: url.clone() };
let store = Arc::new(IpfsStore::new(backend.clone(), timeout));
Ok(ResolvedBackend {
ipfs_backend: backend,
remote: store,
_runtime: None,
})
}
other => Err(CliError::invalid_args(format!(
"invalid backend '{other}': expected daemon, kubo, or gateway"
))),
}
}