nostr_types/types/
client_message.rs1use 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#[derive(Clone, Debug, Eq, PartialEq)]
9pub enum ClientMessage {
10 Event(Box<Event>),
12
13 Req(SubscriptionId, Vec<Filter>),
15
16 Close(SubscriptionId),
18
19 Auth(Box<Event>),
21}
22
23impl ClientMessage {
24 #[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}