nostr_types/types/
event_reference.rs

1use super::{Id, NAddr, PublicKey, RelayUrl};
2use serde::{Deserialize, Serialize};
3use std::hash::{Hash, Hasher};
4
5/// A reference to another event, either by `Id` (often coming from an 'e' tag),
6/// or by `NAddr` (often coming from an 'a' tag).
7#[derive(Clone, Debug, Serialize, Deserialize)]
8pub enum EventReference {
9    /// Refer to a specific event by Id
10    Id {
11        /// The event id
12        id: Id,
13
14        /// Optionally include author (to find via their relay list)
15        author: Option<PublicKey>,
16
17        /// Optionally include relays (to find the event)
18        relays: Vec<RelayUrl>,
19
20        /// Optional marker, if this came from an event tag
21        marker: Option<String>,
22    },
23
24    /// Refer to a replaceable event by NAddr
25    Addr(NAddr),
26}
27
28impl EventReference {
29    /// Get the author
30    pub fn author(&self) -> Option<PublicKey> {
31        match self {
32            EventReference::Id { author, .. } => *author,
33            EventReference::Addr(naddr) => Some(naddr.author),
34        }
35    }
36
37    /// Set the author
38    pub fn set_author(&mut self, new_author: PublicKey) {
39        match self {
40            EventReference::Id { ref mut author, .. } => *author = Some(new_author),
41            EventReference::Addr(ref mut naddr) => naddr.author = new_author,
42        }
43    }
44
45    /// Copy the relays
46    pub fn copy_relays(&self) -> Vec<RelayUrl> {
47        match self {
48            EventReference::Id { relays, .. } => relays.clone(),
49            EventReference::Addr(naddr) => naddr
50                .relays
51                .iter()
52                .filter_map(|r| RelayUrl::try_from_unchecked_url(r).ok())
53                .collect(),
54        }
55    }
56
57    /// Extend relays
58    pub fn extend_relays(&mut self, relays: Vec<RelayUrl>) {
59        let mut new_relays = self.copy_relays();
60        new_relays.extend(relays);
61
62        match self {
63            EventReference::Id { ref mut relays, .. } => *relays = new_relays,
64            EventReference::Addr(ref mut naddr) => {
65                naddr.relays = new_relays.iter().map(|r| r.to_unchecked_url()).collect()
66            }
67        }
68    }
69}
70
71impl PartialEq for EventReference {
72    fn eq(&self, other: &Self) -> bool {
73        match self {
74            EventReference::Id { id: id1, .. } => {
75                match other {
76                    EventReference::Id { id: id2, .. } => {
77                        // We don't compare the other fields which are only helpers,
78                        // not definitive identity
79                        id1 == id2
80                    }
81                    _ => false,
82                }
83            }
84            EventReference::Addr(addr1) => match other {
85                EventReference::Addr(addr2) => addr1 == addr2,
86                _ => false,
87            },
88        }
89    }
90}
91
92impl Eq for EventReference {}
93
94impl Hash for EventReference {
95    fn hash<H: Hasher>(&self, state: &mut H) {
96        match self {
97            EventReference::Id { id, .. } => {
98                // We do not hash the other fields which are only helpers,
99                // not definitive identity
100                id.hash(state);
101            }
102            EventReference::Addr(addr) => {
103                addr.hash(state);
104            }
105        }
106    }
107}