1#![forbid(unsafe_code)]
8#![warn(missing_docs)]
9#![warn(rustdoc::bare_urls)]
10#![warn(clippy::large_futures)]
11
12use std::any::Any;
13use std::collections::HashSet;
14use std::fmt::Debug;
15use std::sync::Arc;
16
17use nostr::prelude::*;
18
19pub mod error;
20pub mod flags;
21pub mod prelude;
22
23use self::error::GossipError;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
27pub enum GossipListKind {
28 Nip17,
30 Nip65,
32}
33
34impl GossipListKind {
35 pub fn to_event_kind(&self) -> Kind {
37 match self {
38 Self::Nip17 => Kind::InboxRelays,
39 Self::Nip65 => Kind::RelayList,
40 }
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
46pub enum GossipPublicKeyStatus {
47 Updated,
49 Outdated {
51 created_at: Option<Timestamp>,
53 },
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub enum BestRelaySelection {
59 All {
61 read: usize,
63 write: usize,
65 hints: usize,
67 most_received: usize,
69 },
70 Read {
72 limit: usize,
74 },
75 Write {
77 limit: usize,
79 },
80 PrivateMessage {
82 limit: usize,
84 },
85 Hints {
87 limit: usize,
89 },
90 MostReceived {
92 limit: usize,
94 },
95}
96
97pub trait NostrGossip: Any + Debug + Send + Sync {
99 fn process<'a>(
103 &'a self,
104 event: &'a Event,
105 relay_url: Option<&'a RelayUrl>,
106 ) -> BoxedFuture<'a, Result<(), GossipError>>;
107
108 fn status<'a>(
110 &'a self,
111 public_key: &'a PublicKey,
112 list: GossipListKind,
113 ) -> BoxedFuture<'a, Result<GossipPublicKeyStatus, GossipError>>;
114
115 fn update_fetch_attempt<'a>(
117 &'a self,
118 public_key: &'a PublicKey,
119 list: GossipListKind,
120 ) -> BoxedFuture<'a, Result<(), GossipError>>;
121
122 fn get_best_relays<'a>(
124 &'a self,
125 public_key: &'a PublicKey,
126 selection: BestRelaySelection,
127 ) -> BoxedFuture<'a, Result<HashSet<RelayUrl>, GossipError>>;
128}
129
130#[doc(hidden)]
131pub trait IntoNostrGossip {
132 fn into_nostr_gossip(self) -> Arc<dyn NostrGossip>;
133}
134
135impl IntoNostrGossip for Arc<dyn NostrGossip> {
136 fn into_nostr_gossip(self) -> Arc<dyn NostrGossip> {
137 self
138 }
139}
140
141impl<T> IntoNostrGossip for T
142where
143 T: NostrGossip + Sized + 'static,
144{
145 fn into_nostr_gossip(self) -> Arc<dyn NostrGossip> {
146 Arc::new(self)
147 }
148}
149
150impl<T> IntoNostrGossip for Arc<T>
151where
152 T: NostrGossip + 'static,
153{
154 fn into_nostr_gossip(self) -> Arc<dyn NostrGossip> {
155 self
156 }
157}