rustev_remote_http/
cancel.rs1use rustev_contract::remote::{CancelSupport, RemoteCode};
7use rustev_contract::run::Charge;
8use rustev_core::seams::{AdapterFailure, AttemptReport, CancelAck, RemoteEnd};
9
10use crate::taxonomy::failure_detail;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct CancelOutcome {
15 pub ack: CancelAck,
16 pub charge: Charge,
17 pub remote: RemoteEnd,
18}
19
20pub fn cancel_outcome(
28 sent: bool,
29 support: CancelSupport,
30 confirmed_charge: Option<Charge>,
31) -> CancelOutcome {
32 if !sent {
33 return CancelOutcome {
34 ack: CancelAck::Stopped,
35 charge: Charge::Observed { units: 0 },
36 remote: RemoteEnd::Finished,
37 };
38 }
39 match (support, confirmed_charge) {
40 (CancelSupport::Confirmed, Some(c)) if c != Charge::Unknown => CancelOutcome {
41 ack: CancelAck::Stopped,
42 charge: c,
43 remote: RemoteEnd::Finished,
44 },
45 _ => CancelOutcome {
46 ack: CancelAck::Unconfirmed,
47 charge: Charge::Unknown,
48 remote: RemoteEnd::PossiblyContinuing,
49 },
50 }
51}
52
53pub fn cancelled_report(outcome: CancelOutcome, detail: &str) -> AttemptReport {
56 AttemptReport {
57 result: Err((
58 AdapterFailure::Cancelled,
59 failure_detail(RemoteCode::Cancelled, detail),
60 )),
61 charge: outcome.charge,
62 cancel: outcome.ack,
63 remote: outcome.remote,
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn stopped_only_when_unsent_or_confirmed() {
73 for support in [
74 CancelSupport::None,
75 CancelSupport::BestEffort,
76 CancelSupport::Confirmed,
77 ] {
78 let o = cancel_outcome(false, support, None);
79 assert_eq!(
80 (o.ack, o.charge),
81 (CancelAck::Stopped, Charge::Observed { units: 0 })
82 );
83 let o = cancel_outcome(true, support, None);
84 assert_eq!((o.ack, o.charge), (CancelAck::Unconfirmed, Charge::Unknown));
85 assert_eq!(o.remote, RemoteEnd::PossiblyContinuing);
86 }
87 let c = Some(Charge::Observed { units: 2 });
88 assert_eq!(
89 cancel_outcome(true, CancelSupport::Confirmed, c).ack,
90 CancelAck::Stopped
91 );
92 assert_eq!(
94 cancel_outcome(true, CancelSupport::BestEffort, c).ack,
95 CancelAck::Unconfirmed
96 );
97 assert_eq!(
99 cancel_outcome(true, CancelSupport::Confirmed, Some(Charge::Unknown)).ack,
100 CancelAck::Unconfirmed
101 );
102 }
103}