message.rs (2400B)
1 use crate::Error; 2 use nostrdb::{Filter, Note}; 3 use serde_json::json; 4 5 #[derive(Debug, Clone)] 6 pub struct EventClientMessage { 7 pub note_json: String, 8 } 9 10 impl EventClientMessage { 11 pub fn to_json(&self) -> String { 12 format!("[\"EVENT\", {}]", self.note_json) 13 } 14 } 15 16 impl<'a> TryFrom<&'a Note<'a>> for EventClientMessage { 17 type Error = Error; 18 19 fn try_from(value: &'a Note<'a>) -> Result<Self, Self::Error> { 20 Ok(Self { 21 note_json: value.json()?, 22 }) 23 } 24 } 25 26 impl From<EventClientMessage> for ClientMessage { 27 fn from(value: EventClientMessage) -> Self { 28 ClientMessage::Event(value) 29 } 30 } 31 32 /// Messages sent by clients, received by relays 33 #[derive(Debug, Clone)] 34 pub enum ClientMessage { 35 Event(EventClientMessage), 36 Req { 37 sub_id: String, 38 filters: Vec<Filter>, 39 }, 40 Close { 41 sub_id: String, 42 }, 43 Raw(String), 44 } 45 46 impl ClientMessage { 47 pub fn event(note: &Note) -> Result<Self, Error> { 48 Ok(ClientMessage::Event(EventClientMessage { 49 note_json: note.json()?, 50 })) 51 } 52 53 pub fn event_json(note_json: String) -> Result<Self, Error> { 54 Ok(ClientMessage::Event(EventClientMessage { note_json })) 55 } 56 57 pub fn req(sub_id: String, filters: Vec<Filter>) -> Self { 58 ClientMessage::Req { sub_id, filters } 59 } 60 61 pub fn close(sub_id: String) -> Self { 62 ClientMessage::Close { sub_id } 63 } 64 65 pub fn to_json(&self) -> Result<String, Error> { 66 Ok(match self { 67 Self::Event(ecm) => ecm.to_json(), 68 Self::Raw(raw) => raw.clone(), 69 Self::Req { sub_id, filters } => { 70 if filters.is_empty() { 71 format!("[\"REQ\",\"{sub_id}\",{{ }}]") 72 } else if filters.len() == 1 { 73 let filters_json_str = filters[0].json()?; 74 format!("[\"REQ\",\"{sub_id}\",{filters_json_str}]") 75 } else { 76 let filters_json_str: Result<Vec<String>, Error> = filters 77 .iter() 78 .map(|f| f.json().map_err(Into::<Error>::into)) 79 .collect(); 80 format!("[\"REQ\",\"{}\",{}]", sub_id, filters_json_str?.join(",")) 81 } 82 } 83 Self::Close { sub_id } => json!(["CLOSE", sub_id]).to_string(), 84 }) 85 } 86 }