From aa4bfbef233ccb84500faed6e98c7eff09470a51 Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Sat, 17 Feb 2024 12:36:31 +1300 Subject: [PATCH] Stronger typing for reply message prefixes (plus fixed one) --- src/nostr.rs | 13 +++++++------ src/reply.rs | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/nostr.rs b/src/nostr.rs index e70dd7a..79e9be0 100644 --- a/src/nostr.rs +++ b/src/nostr.rs @@ -1,6 +1,6 @@ use crate::error::{ChorusError, Error}; use crate::globals::GLOBALS; -use crate::reply::NostrReply; +use crate::reply::{NostrReply, NostrReplyPrefix}; use crate::types::parse::json_escape::json_unescape; use crate::types::parse::json_parse::*; use crate::types::{Event, Filter, Kind, OwnedFilter}; @@ -128,7 +128,8 @@ impl WebSocketService { let reply = NostrReply::Ok( event.id(), false, - "blocked: this personal relay only accepts events related to its users".to_owned(), + NostrReplyPrefix::Blocked, + "this personal relay only accepts events related to its users".to_owned(), ); self.websocket.send(Message::text(reply.as_json())).await?; return Ok(()); @@ -138,13 +139,13 @@ impl WebSocketService { let reply = match GLOBALS.store.get().unwrap().store_event(&event) { Ok(offset) => { GLOBALS.new_events.send(offset)?; // advertise the new event - NostrReply::Ok(event.id(), true, "".to_owned()) + NostrReply::Ok(event.id(), true, NostrReplyPrefix::None, "".to_owned()) } Err(e) => { if matches!(e.inner, ChorusError::Duplicate) { - NostrReply::Ok(event.id(), true, "duplicate:".to_owned()) + NostrReply::Ok(event.id(), true, NostrReplyPrefix::Duplicate, "".to_owned()) } else { - NostrReply::Ok(event.id(), false, format!("{e}")) + NostrReply::Ok(event.id(), false, NostrReplyPrefix::Error, format!("{e}")) } } }; @@ -173,7 +174,7 @@ impl WebSocketService { let reply = if self.subscriptions.contains_key(subid) { // Remove it, and let them know self.subscriptions.remove(subid); - NostrReply::Closed(subid, "".to_owned()) + NostrReply::Closed(subid, NostrReplyPrefix::None, "".to_owned()) } else { NostrReply::Notice(format!("no such subscription id: {}", subid)) }; diff --git a/src/reply.rs b/src/reply.rs index 45dda57..5f59a5c 100644 --- a/src/reply.rs +++ b/src/reply.rs @@ -1,11 +1,35 @@ use crate::types::{Event, Id}; use std::fmt; +pub enum NostrReplyPrefix { + None, + Pow, + Duplicate, + Blocked, + RateLimited, + Invalid, + Error, +} + +impl fmt::Display for NostrReplyPrefix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + NostrReplyPrefix::None => Ok(()), + NostrReplyPrefix::Pow => write!(f, "pow: "), + NostrReplyPrefix::Duplicate => write!(f, "duplicate: "), + NostrReplyPrefix::Blocked => write!(f, "blocked: "), + NostrReplyPrefix::RateLimited => write!(f, "rate-limited: "), + NostrReplyPrefix::Invalid => write!(f, "invalid: "), + NostrReplyPrefix::Error => write!(f, "error: "), + } + } +} + pub enum NostrReply<'a> { Event(&'a str, Event<'a>), - Ok(Id, bool, String), + Ok(Id, bool, NostrReplyPrefix, String), Eose(&'a str), - Closed(&'a str, String), + Closed(&'a str, NostrReplyPrefix, String), Notice(String), } @@ -13,9 +37,11 @@ impl NostrReply<'_> { pub fn as_json(&self) -> String { match self { NostrReply::Event(subid, event) => format!(r#"["EVENT", "{subid}", {}]"#, event), - NostrReply::Ok(id, ok, msg) => format!(r#"["OK","{id}",{ok},"{msg}"]"#), + NostrReply::Ok(id, ok, prefix, msg) => format!(r#"["OK","{id}",{ok},"{prefix}{msg}"]"#), NostrReply::Eose(subid) => format!(r#"["EOSE","{subid}"]"#), - NostrReply::Closed(subid, msg) => format!(r#"["CLOSED","{subid}","{msg}"]"#), + NostrReply::Closed(subid, prefix, msg) => { + format!(r#"["CLOSED","{subid}","{prefix}{msg}"]"#) + } NostrReply::Notice(msg) => format!(r#"["NOTICE","{msg}"]"#), } }