use std::sync::Arc;
use nostr::event::Kind;
use nostr::filter::{Filter, SingleLetterTag};
use nostr_gossip::NostrGossip;
mod refresher;
mod resolver;
mod semaphore;
mod updater;
use self::refresher::*;
pub(super) use self::resolver::*;
pub(super) use self::semaphore::*;
pub(super) enum GossipFilterPattern {
Nip65,
Nip65AndNip17,
}
impl GossipFilterPattern {
#[inline]
fn has_nip17(&self) -> bool {
matches!(self, Self::Nip65AndNip17)
}
}
pub(super) fn find_filter_pattern(filter: &Filter) -> GossipFilterPattern {
let (are_kinds_empty, has_gift_wrap_kind): (bool, bool) = match &filter.kinds {
Some(kinds) if kinds.is_empty() => (true, false),
Some(kinds) => (false, kinds.contains(&Kind::GiftWrap)),
None => (true, false),
};
let has_p_tags: bool = filter
.generic_tags
.contains_key(&SingleLetterTag::LOWERCASE_P);
if has_gift_wrap_kind || (has_p_tags && are_kinds_empty) {
return GossipFilterPattern::Nip65AndNip17;
}
GossipFilterPattern::Nip65
}
#[derive(Debug)]
pub(super) struct Gossip {
store: Arc<dyn NostrGossip>,
resolver: GossipRelayResolver,
semaphore: GossipSemaphore,
refresher: GossipBackgroundRefresher,
}
impl Gossip {
#[inline]
pub(super) fn new(gossip: Arc<dyn NostrGossip>) -> Self {
Self {
store: gossip.clone(),
resolver: GossipRelayResolver::new(gossip),
semaphore: GossipSemaphore::new(),
refresher: GossipBackgroundRefresher::new(),
}
}
#[inline]
pub(super) fn store(&self) -> &Arc<dyn NostrGossip> {
&self.store
}
#[inline]
pub(super) fn resolver(&self) -> &GossipRelayResolver {
&self.resolver
}
#[inline]
pub(super) fn semaphore(&self) -> &GossipSemaphore {
&self.semaphore
}
#[inline]
fn refresher(&self) -> &GossipBackgroundRefresher {
&self.refresher
}
#[cfg(test)]
pub(super) fn is_background_refresher_spawned(&self) -> bool {
self.refresher.is_background_refresher_spawned()
}
}