mod api;
mod download;
mod error;
mod folder;
mod list;
mod model;
mod rename;
mod transfer;
mod upload;
#[cfg(not(any(
feature = "default-tls",
feature = "native-tls",
feature = "native-tls-vendored",
feature = "rustls",
feature = "rustls-no-provider",
)))]
compile_error!("enable exactly one TLS backend feature for libquarkpan");
#[cfg(any(
all(feature = "default-tls", feature = "native-tls"),
all(feature = "default-tls", feature = "native-tls-vendored"),
all(feature = "default-tls", feature = "rustls"),
all(feature = "default-tls", feature = "rustls-no-provider"),
all(feature = "native-tls", feature = "native-tls-vendored"),
all(feature = "native-tls", feature = "rustls"),
all(feature = "native-tls", feature = "rustls-no-provider"),
all(feature = "native-tls-vendored", feature = "rustls"),
all(feature = "native-tls-vendored", feature = "rustls-no-provider"),
all(feature = "rustls", feature = "rustls-no-provider"),
))]
compile_error!("enable only one TLS backend feature for libquarkpan");
pub use crate::download::{DownloadBuilder, DownloadRequest};
pub use crate::error::{QuarkPanError, Result};
pub use crate::folder::CreateFolderBuilder;
pub use crate::list::{ListBuilder, ListRequest};
pub use crate::model::{
DownloadInfo, Fid, ListPage, QuarkEntry, UploadComplete, UploadPrepareResult, UploadResume,
UploadResumeState, UploadSession,
};
pub use crate::rename::{RenameBuilder, RenameRequest};
pub use crate::transfer::{ProgressStream, TransferControl, TransferProgress};
pub use crate::upload::UploadBuilder;
use std::sync::Arc;
use api::{ApiClient, ApiConfig};
use dashmap::DashMap;
#[derive(Clone)]
pub struct QuarkPan {
inner: Arc<QuarkPanInner>,
}
struct QuarkPanInner {
api: ApiClient,
}
impl QuarkPan {
pub fn builder() -> QuarkPanBuilder {
QuarkPanBuilder::default()
}
pub fn download(&self) -> DownloadBuilder {
DownloadBuilder::new(self.inner.clone())
}
pub fn upload(&self) -> UploadBuilder {
UploadBuilder::new(self.inner.clone())
}
pub fn create_folder(&self) -> CreateFolderBuilder {
CreateFolderBuilder::new(self.inner.clone())
}
pub fn list(&self) -> ListBuilder {
ListBuilder::new(self.inner.clone())
}
pub fn rename(&self) -> RenameBuilder {
RenameBuilder::new(self.inner.clone())
}
pub async fn delete<S>(&self, fids: &[S]) -> Result<()>
where
S: AsRef<str>,
{
self.inner.api.delete(fids).await
}
}
#[derive(Default)]
pub struct QuarkPanBuilder {
cookie: Option<String>,
api_base_url: Option<String>,
}
impl QuarkPanBuilder {
pub fn cookie(mut self, cookie: impl Into<String>) -> Self {
self.cookie = Some(cookie.into());
self
}
pub fn api_base_url(mut self, api_base_url: impl Into<String>) -> Self {
self.api_base_url = Some(api_base_url.into());
self
}
pub fn prepare(self) -> Result<QuarkPan> {
let cookie = self
.cookie
.ok_or_else(|| QuarkPanError::missing_field("cookie"))?;
let cookie_map = Arc::new(DashMap::new());
for pair in cookie.split(';') {
if let Some((k, v)) = pair.trim().split_once('=') {
cookie_map.insert(k.trim().to_string(), v.trim().to_string());
}
}
if cookie_map.is_empty() {
return Err(QuarkPanError::invalid_argument(
"cookie must contain at least one key=value pair",
));
}
let api = ApiClient::new(ApiConfig {
api_base_url: self
.api_base_url
.unwrap_or_else(|| "https://drive.quark.cn".to_string()),
cookie: cookie_map,
})?;
Ok(QuarkPan {
inner: Arc::new(QuarkPanInner { api }),
})
}
}