use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CdnEndpoint {
pub url: String,
pub priority: u32,
pub region: Option<String>,
pub supports_range: bool,
pub max_connections: usize,
pub headers: Vec<(String, String)>,
}
impl CdnEndpoint {
pub fn new(url: impl Into<String>) -> Self {
Self {
url: url.into(),
priority: 0,
region: None,
supports_range: true,
max_connections: 8,
headers: Vec::new(),
}
}
pub fn with_priority(mut self, priority: u32) -> Self {
self.priority = priority;
self
}
pub fn with_region(mut self, region: impl Into<String>) -> Self {
self.region = Some(region.into());
self
}
pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.push((key.into(), value.into()));
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetryConfig {
pub max_retries: u32,
pub initial_backoff: Duration,
pub max_backoff: Duration,
pub multiplier: f64,
pub jitter: bool,
}
impl Default for RetryConfig {
fn default() -> Self {
Self {
max_retries: 3,
initial_backoff: Duration::from_millis(100),
max_backoff: Duration::from_secs(10),
multiplier: 2.0,
jitter: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkConfig {
pub endpoints: Vec<CdnEndpoint>,
pub timeout: Duration,
pub connect_timeout: Duration,
pub max_concurrent: usize,
pub chunk_size: usize,
pub retry: RetryConfig,
pub compression: bool,
pub user_agent: String,
pub cache_dir: Option<std::path::PathBuf>,
pub max_cache_size: u64,
pub monitor_bandwidth: bool,
pub min_bandwidth: u64,
}
impl Default for NetworkConfig {
fn default() -> Self {
Self {
endpoints: Vec::new(),
timeout: Duration::from_secs(30),
connect_timeout: Duration::from_secs(10),
max_concurrent: 4,
chunk_size: 1024 * 1024, retry: RetryConfig::default(),
compression: true,
user_agent: format!("haagenti-network/{}", env!("CARGO_PKG_VERSION")),
cache_dir: None,
max_cache_size: 10 * 1024 * 1024 * 1024, monitor_bandwidth: true,
min_bandwidth: 1024 * 1024, }
}
}
impl NetworkConfig {
pub fn with_endpoint(mut self, endpoint: CdnEndpoint) -> Self {
self.endpoints.push(endpoint);
self
}
pub fn with_cache_dir(mut self, path: impl Into<std::path::PathBuf>) -> Self {
self.cache_dir = Some(path.into());
self
}
pub fn with_max_concurrent(mut self, max: usize) -> Self {
self.max_concurrent = max;
self
}
pub fn huggingface_hub() -> Self {
Self::default()
.with_endpoint(
CdnEndpoint::new("https://huggingface.co")
.with_priority(0)
.with_region("global"),
)
.with_endpoint(
CdnEndpoint::new("https://cdn-lfs.huggingface.co")
.with_priority(1)
.with_region("global"),
)
}
pub fn civitai() -> Self {
Self::default()
.with_endpoint(CdnEndpoint::new("https://civitai.com/api/download").with_priority(0))
}
pub fn custom_cdn(base_url: impl Into<String>) -> Self {
Self::default().with_endpoint(CdnEndpoint::new(base_url))
}
}