spop/frames/
ack.rs

1use crate::{
2    SpopFrame,
3    actions::{Action, VarScope},
4    frame::{FrameFlags, FramePayload, FrameType, Metadata},
5    types::TypedData,
6};
7
8/// Frame Ack
9///
10/// <https://github.com/haproxy/haproxy/blob/master/doc/SPOE.txt#L949>
11///
12/// ```text
13/// 3.2.7. Frame: ACK
14/// ------------------
15///
16/// ACK frames must be sent by agents to reply to NOTIFY frames. STREAM-ID and
17/// FRAME-ID found in a NOTIFY frame must be reuse in the corresponding ACK
18/// frame. The payload of ACK frames is a LIST-OF-ACTIONS.
19/// ```
20#[derive(Debug, Clone)]
21pub struct Ack {
22    pub stream_id: u64,
23    pub frame_id: u64,
24    pub actions: Vec<Action>,
25}
26
27impl Ack {
28    /// Creates a new ACK frame with no actions
29    pub const fn new(stream_id: u64, frame_id: u64) -> Self {
30        Self {
31            stream_id,
32            frame_id,
33            actions: Vec::new(),
34        }
35    }
36
37    /// Adds a set-var action to the ACK frame
38    pub fn set_var(mut self, scope: VarScope, name: &str, value: impl Into<TypedData>) -> Self {
39        self.actions.push(Action::SetVar {
40            scope,
41            name: name.to_string(),
42            value: value.into(),
43        });
44        self
45    }
46
47    // Adds an unset-var action to the ACK frame
48    pub fn unset_var(mut self, scope: VarScope, name: &str) -> Self {
49        self.actions.push(Action::UnSetVar {
50            scope,
51            name: name.to_string(),
52        });
53        self
54    }
55}
56
57/// Serializes the ACK frame into a `Frame` structure
58impl SpopFrame for Ack {
59    fn frame_type(&self) -> &FrameType {
60        &FrameType::Ack
61    }
62
63    fn metadata(&self) -> Metadata {
64        Metadata {
65            flags: FrameFlags::new(true, false), // FIN flag set, ABORT flag not set
66            stream_id: self.stream_id,
67            frame_id: self.frame_id,
68        }
69    }
70
71    fn payload(&self) -> FramePayload {
72        FramePayload::ListOfActions(self.actions.clone())
73    }
74}