Skip to main content

bsv_messagebox_client/
delivery.rs

1/// Result of a [`send_live_message`](crate::client::MessageBoxClient::send_live_message) call.
2///
3/// The WebSocket path waits up to 10 seconds for a `sendMessageAck`
4/// event from the server. If the ack arrives, the message was
5/// relayed to any live subscribers and delivery is `Live`. If the ack
6/// times out, the client falls back to the HTTP POST /sendMessage
7/// endpoint, which persists the message durably — the message IS
8/// stored, but no live push was confirmed (recipients must poll or
9/// be subscribed). Use `Live` when your protocol requires the peer
10/// to have received the message in real time.
11#[derive(Debug, Clone)]
12pub enum DeliveryMode {
13    /// Delivered via WebSocket — server acked within the 10s window.
14    Live { message_id: String },
15    /// Persisted via HTTP fallback — WS ack timed out. Recipient must
16    /// poll or already be subscribed to receive it.
17    Persisted { message_id: String },
18}
19
20impl DeliveryMode {
21    /// Return the server-assigned message ID, regardless of delivery mode.
22    pub fn message_id(&self) -> &str {
23        match self {
24            Self::Live { message_id } | Self::Persisted { message_id } => message_id,
25        }
26    }
27
28    /// Return true if the message was acked live via WS.
29    pub fn is_live(&self) -> bool {
30        matches!(self, Self::Live { .. })
31    }
32}
33
34// ---------------------------------------------------------------------------
35// Tests
36// ---------------------------------------------------------------------------
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    /// DeliveryMode::message_id returns the correct ID for both variants.
43    #[test]
44    fn delivery_mode_message_id_both_variants() {
45        let live = DeliveryMode::Live {
46            message_id: "live-msg-001".to_string(),
47        };
48        assert_eq!(live.message_id(), "live-msg-001", "Live variant message_id");
49        assert!(live.is_live(), "Live variant is_live() must be true");
50
51        let persisted = DeliveryMode::Persisted {
52            message_id: "http-msg-002".to_string(),
53        };
54        assert_eq!(
55            persisted.message_id(),
56            "http-msg-002",
57            "Persisted variant message_id"
58        );
59        assert!(!persisted.is_live(), "Persisted variant is_live() must be false");
60    }
61
62    /// DeliveryMode implements Clone — both variants clone without panic.
63    #[test]
64    fn delivery_mode_clone() {
65        let live = DeliveryMode::Live {
66            message_id: "abc".to_string(),
67        };
68        let cloned = live.clone();
69        assert_eq!(live.message_id(), cloned.message_id());
70
71        let persisted = DeliveryMode::Persisted {
72            message_id: "xyz".to_string(),
73        };
74        let cloned_p = persisted.clone();
75        assert_eq!(persisted.message_id(), cloned_p.message_id());
76    }
77
78    /// DeliveryMode implements Debug — both variants format without panic.
79    #[test]
80    fn delivery_mode_debug() {
81        let live = DeliveryMode::Live {
82            message_id: "dbg-live".to_string(),
83        };
84        let s = format!("{live:?}");
85        assert!(s.contains("Live"), "Debug output must mention variant");
86
87        let persisted = DeliveryMode::Persisted {
88            message_id: "dbg-persisted".to_string(),
89        };
90        let s2 = format!("{persisted:?}");
91        assert!(s2.contains("Persisted"), "Debug output must mention variant");
92    }
93}