1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
use std::convert::TryFrom;
/// A way that a user uses a Relay
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[repr(u32)]
pub enum RelayUsage {
/// User seeks events here if they are not otherwise found
FallbackRead = 1 << 0,
/// User writes here but does not advertise it
Archive = 1 << 1,
// was a relay usage flag in gossip, but was retired
// Advertise = 1 << 2,
/// User accepts posts here from the public that tag them
Inbox = 1 << 3,
/// User posts here for the public
Outbox = 1 << 4,
/// User seeks relay lists here (index, discover)
Directory = 1 << 5,
// is used as SPAMSAFE bit in gossip so reserved, but isn't a relay usage
// ReservedSpamsafe = 1 << 6,
/// User accepts DMs here
Dm = 1 << 7,
/// user stores and reads back their own configurations here
Config = 1 << 8,
/// User does NIP-50 SEARCH here
Search = 1 << 9,
}
impl TryFrom<u32> for RelayUsage {
type Error = ();
fn try_from(u: u32) -> Result<RelayUsage, ()> {
match u {
1 => Ok(RelayUsage::FallbackRead),
2 => Ok(RelayUsage::Archive),
8 => Ok(RelayUsage::Inbox),
16 => Ok(RelayUsage::Outbox),
32 => Ok(RelayUsage::Directory),
128 => Ok(RelayUsage::Dm),
256 => Ok(RelayUsage::Config),
512 => Ok(RelayUsage::Search),
_ => Err(()),
}
}
}
/// The ways that a user uses a Relay
///
// See also https://github.com/mikedilger/gossip/blob/master/gossip-lib/src/storage/types/relay3.rs
// See also https://github.com/nostr-protocol/nips/issues/1282 for possible future entries
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
pub struct RelayUsageSet(u32);
impl RelayUsageSet {
const MASK: u32 = RelayUsage::FallbackRead as u32
| RelayUsage::Archive as u32
| RelayUsage::Inbox as u32
| RelayUsage::Outbox as u32
| RelayUsage::Directory as u32
| RelayUsage::Dm as u32
| RelayUsage::Config as u32
| RelayUsage::Search as u32;
/// Create a new empty RelayUsageSet
pub const fn new_empty() -> Self {
RelayUsageSet(0)
}
/// Create a new RelayUsageSet with all usages
pub const fn new_all() -> Self {
Self(Self::MASK)
}
/// Get the u32 bitflag representation
pub const fn bits(&self) -> u32 {
self.0
}
/// Set from a u32 bitflag representation. If any unknown bits are set,
/// this will return None
pub const fn from_bits(bits: u32) -> Option<RelayUsageSet> {
if bits & !Self::MASK != 0 {
None
} else {
Some(RelayUsageSet(bits))
}
}
/// Set from a u32 bitflag representation. If any unknown bits are set,
/// they will be cleared
pub const fn from_bits_truncate(bits: u32) -> RelayUsageSet {
RelayUsageSet(bits & Self::MASK)
}
/// Whether all bits are unset
pub const fn is_empty(&self) -> bool {
self.0 == 0
}
/// Whether all defined bits are set
pub const fn is_all(&self) -> bool {
self.0 & Self::MASK == Self::MASK
}
/// Whether any usage in other is also in Self
pub const fn intersects(&self, other: Self) -> bool {
self.0 & other.0 != 0
}
/// Whether all usages in other are in Self
pub const fn contains(&self, other: Self) -> bool {
self.0 & other.0 == other.0
}
/// Has a RelayUsage set
pub fn has_usage(&mut self, ru: RelayUsage) -> bool {
self.0 & ru as u32 == ru as u32
}
/// Add a RelayUsage to Self
pub fn add_usage(&mut self, ru: RelayUsage) {
self.0 |= ru as u32
}
/// Remove a RelayUsage to Self
pub fn remove_usage(&mut self, ru: RelayUsage) {
self.0 = self.0 & !(ru as u32)
}
}