use std::borrow::Cow;
use bytes::Bytes;
use http_cache_stream_reqwest::Cache;
use http_cache_stream_reqwest::storage::DefaultCacheStorage;
use reqwest::Response;
use tokio::sync::broadcast;
use url::Url;
use crate::Config;
use crate::Result;
use crate::TransferEvent;
pub(crate) mod auth;
pub(crate) mod azure;
pub(crate) mod generic;
pub(crate) mod google;
pub(crate) mod s3;
fn format_range_header(start: u64, exclusive_end: Option<u64>) -> String {
exclusive_end
.map(|end| format!("bytes={start}-{end}", end = end.strict_sub(1)))
.unwrap_or_else(|| format!("bytes={start}-"))
}
pub trait Upload: Send + Sync + 'static {
type Part: Default + Clone + Send;
fn put(
&self,
id: u64,
block: u64,
bytes: Bytes,
) -> impl Future<Output = Result<Option<Self::Part>>> + Send;
fn finalize(&self, parts: &[Self::Part]) -> impl Future<Output = Result<()>> + Send;
}
pub trait StorageBackend {
type Upload: Upload;
fn config(&self) -> &Config;
fn cache(&self) -> Option<&Cache<DefaultCacheStorage>>;
fn events(&self) -> &Option<broadcast::Sender<TransferEvent>>;
fn block_size(&self, file_size: u64) -> Result<u64>;
fn is_supported_url(config: &Config, url: &Url) -> bool;
fn rewrite_url<'a>(config: &Config, url: &'a Url) -> Result<Cow<'a, Url>>;
fn join_url<'a>(&self, url: Url, segments: impl Iterator<Item = &'a str>) -> Result<Url>;
fn head(&self, url: Url, must_exist: bool) -> impl Future<Output = Result<Response>> + Send;
fn get(&self, url: Url) -> impl Future<Output = Result<Response>> + Send;
fn get_range(
&self,
url: Url,
etag: &str,
start: u64,
exclusive_end: Option<u64>,
) -> impl Future<Output = Result<Response>> + Send;
fn walk(&self, url: Url, first_only: bool) -> impl Future<Output = Result<Vec<String>>> + Send;
fn new_upload(
&self,
url: Url,
digest: Option<String>,
) -> impl Future<Output = Result<Self::Upload>> + Send;
}