use super::*;
pub(super) struct Attempt {
pub(super) id: u64,
pub(super) session: tau_proto::SessionId,
pub(super) text: Arc<str>,
pub(super) upload: tau_client::ArtifactUpload,
pub(super) handle: tau_cli_term::TermHandle,
pub(super) available: bool,
pub(super) paused: bool,
pub(super) deadline: Instant,
pub(super) request: Option<ArtifactRequestId>,
}
impl Attempt {
pub(super) fn fail(&mut self, error: impl ToString) {
self.paused = true;
self.request = None;
self.handle
.finish_paste_upload(self.id, Err(error.to_string()));
}
pub(super) fn send_next(
&mut self,
writer: &WriterHandle,
expected: &Mutex<Option<ArtifactRequestId>>,
) {
if Instant::now() >= self.deadline {
self.fail("upload timed out");
return;
}
let op = if self.available {
self.upload.next_op().expect("unfinished upload operation")
} else {
ArtifactOp::Available
};
let request = request(&self.session, op);
self.request = Some(request.request_id.clone());
*expected.lock().expect("paste correlation poisoned") = self.request.clone();
if let Err(error) = send_frame(writer, &HarnessInputMessage::ArtifactRequest(request)) {
*expected.lock().expect("paste correlation poisoned") = None;
self.fail(error);
}
}
pub(super) fn accept(&mut self, result: ArtifactResult) -> Result<(), String> {
let value = result.result.map_err(|error| error.to_string())?;
if self.available {
self.upload.accept(value).map_err(|error| error.to_string())
} else if matches!(value, ArtifactValue::Done) {
self.available = true;
Ok(())
} else {
Err("invalid upload availability response".to_owned())
}
}
pub(super) fn abort(&self, writer: &WriterHandle) {
if let Some(op) = self.upload.abort_op() {
let _ = send_frame(
writer,
&HarnessInputMessage::ArtifactRequest(request(&self.session, op)),
);
}
}
}