nostr_types/types/
client_message.rs

1use super::{Event, Filter, SubscriptionId};
2use serde::de::Error as DeError;
3use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
4use serde::ser::{Serialize, SerializeSeq, Serializer};
5use std::fmt;
6
7/// A message from a client to a relay
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub enum ClientMessage {
10    /// An event
11    Event(Box<Event>),
12
13    /// A subscription request
14    Req(SubscriptionId, Vec<Filter>),
15
16    /// A request to close a subscription
17    Close(SubscriptionId),
18
19    /// Used to send authentication events
20    Auth(Box<Event>),
21}
22
23impl ClientMessage {
24    // Mock data for testing
25    #[allow(dead_code)]
26    pub(crate) fn mock() -> ClientMessage {
27        ClientMessage::Event(Box::new(Event::mock()))
28    }
29}
30
31impl Serialize for ClientMessage {
32    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33    where
34        S: Serializer,
35    {
36        match self {
37            ClientMessage::Event(event) => {
38                let mut seq = serializer.serialize_seq(Some(2))?;
39                seq.serialize_element("EVENT")?;
40                seq.serialize_element(&event)?;
41                seq.end()
42            }
43            ClientMessage::Req(id, filters) => {
44                let mut seq = serializer.serialize_seq(Some(3))?;
45                seq.serialize_element("REQ")?;
46                seq.serialize_element(&id)?;
47                for filter in filters {
48                    seq.serialize_element(&filter)?;
49                }
50                seq.end()
51            }
52            ClientMessage::Close(id) => {
53                let mut seq = serializer.serialize_seq(Some(2))?;
54                seq.serialize_element("CLOSE")?;
55                seq.serialize_element(&id)?;
56                seq.end()
57            }
58            ClientMessage::Auth(event) => {
59                let mut seq = serializer.serialize_seq(Some(2))?;
60                seq.serialize_element("AUTH")?;
61                seq.serialize_element(&event)?;
62                seq.end()
63            }
64        }
65    }
66}
67
68impl<'de> Deserialize<'de> for ClientMessage {
69    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70    where
71        D: Deserializer<'de>,
72    {
73        deserializer.deserialize_seq(ClientMessageVisitor)
74    }
75}
76
77struct ClientMessageVisitor;
78
79impl<'de> Visitor<'de> for ClientMessageVisitor {
80    type Value = ClientMessage;
81
82    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
83        write!(f, "a sequence of strings")
84    }
85
86    fn visit_seq<A>(self, mut seq: A) -> Result<ClientMessage, A::Error>
87    where
88        A: SeqAccess<'de>,
89    {
90        let word: &str = seq
91            .next_element()?
92            .ok_or_else(|| DeError::custom("Message missing initial string field"))?;
93        if word == "EVENT" {
94            let event: Event = seq
95                .next_element()?
96                .ok_or_else(|| DeError::custom("Message missing event field"))?;
97            Ok(ClientMessage::Event(Box::new(event)))
98        } else if word == "REQ" {
99            let id: SubscriptionId = seq
100                .next_element()?
101                .ok_or_else(|| DeError::custom("Message missing id field"))?;
102            let mut filters: Vec<Filter> = vec![];
103            loop {
104                let f: Option<Filter> = seq.next_element()?;
105                match f {
106                    None => break,
107                    Some(fil) => filters.push(fil),
108                }
109            }
110            Ok(ClientMessage::Req(id, filters))
111        } else if word == "CLOSE" {
112            let id: SubscriptionId = seq
113                .next_element()?
114                .ok_or_else(|| DeError::custom("Message missing id field"))?;
115            Ok(ClientMessage::Close(id))
116        } else if word == "AUTH" {
117            let event: Event = seq
118                .next_element()?
119                .ok_or_else(|| DeError::custom("Message missing event field"))?;
120            Ok(ClientMessage::Auth(Box::new(event)))
121        } else {
122            Err(DeError::custom(format!("Unknown Message: {}", word)))
123        }
124    }
125}
126
127#[cfg(test)]
128mod test {
129    use super::*;
130
131    test_serde! {ClientMessage, test_client_message_serde}
132}