use std::ops::ControlFlow;
use std::sync::atomic::AtomicBool;
use super::{CloneHead, CloneReady, CloneRequest, CloneTransferError, plan, workflow};
use crate::fetch::{DownloadedFetch, FetchLimits};
use crate::transport::TransportControl;
#[derive(Debug)]
pub struct CloneDownload {
request: CloneRequest,
head: CloneHead,
downloaded: DownloadedFetch,
}
impl CloneDownload {
pub fn validate(
self,
cancel: &AtomicBool,
progress: impl FnMut(&[u8]) -> ControlFlow<()>,
) -> Result<CloneReady, CloneTransferError> {
Ok(CloneReady {
request: self.request,
head: self.head,
received: self.downloaded.validate(cancel, progress)?,
})
}
}
impl CloneRequest {
#[cfg(feature = "http")]
pub async fn receive_http(
self,
remote: &crate::transport::http::HttpRemote,
limits: FetchLimits,
control: TransportControl<'_>,
) -> Result<CloneDownload, CloneTransferError> {
let mut saved = None;
let download = crate::fetch::receive_http(
remote,
|ad| plan::select(self.plan(ad), &mut saved),
None,
limits,
control,
)
.await;
let (plan, downloaded) = workflow::selected(saved, download)?;
Ok(CloneDownload {
request: self,
head: plan.head,
downloaded,
})
}
#[cfg(all(feature = "ssh", any(target_os = "macos", target_os = "linux")))]
pub async fn receive_ssh(
self,
remote: &crate::transport::ssh::SshRemote,
limits: FetchLimits,
control: TransportControl<'_>,
) -> Result<CloneDownload, CloneTransferError> {
let mut saved = None;
let download = crate::fetch::receive_ssh(
remote,
|ad| plan::select(self.plan(ad), &mut saved),
None,
limits,
control,
)
.await;
let (plan, downloaded) = workflow::selected(saved, download)?;
Ok(CloneDownload {
request: self,
head: plan.head,
downloaded,
})
}
}