Skip to content

Commit

Permalink
nostr: add support to uppercase single-letter tags
Browse files Browse the repository at this point in the history
Add `SingleLetterTag`
  • Loading branch information
yukibtc committed Jan 23, 2024
1 parent 2c404d0 commit 17a5447
Show file tree
Hide file tree
Showing 7 changed files with 344 additions and 191 deletions.
54 changes: 48 additions & 6 deletions bindings/nostr-ffi/src/message/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,44 @@ impl From<Alphabet> for subscription::Alphabet {
}
}

#[derive(Object)]
pub struct SingleLetterTag {
inner: subscription::SingleLetterTag,
}

impl Deref for SingleLetterTag {
type Target = subscription::SingleLetterTag;

fn deref(&self) -> &Self::Target {
&self.inner
}
}

#[uniffi::export]
impl SingleLetterTag {
#[uniffi::constructor]
pub fn lowercase(character: Alphabet) -> Self {
Self {
inner: subscription::SingleLetterTag::lowercase(character.into()),
}
}

#[uniffi::constructor]
pub fn uppercase(character: Alphabet) -> Self {
Self {
inner: subscription::SingleLetterTag::uppercase(character.into()),
}
}

pub fn is_lowercase(&self) -> bool {
self.inner.is_lowercase()
}

pub fn is_uppercase(&self) -> bool {
self.inner.is_uppercase()
}
}

#[derive(Clone, Object)]
pub struct Filter {
inner: nostr::Filter,
Expand Down Expand Up @@ -313,16 +351,20 @@ impl Filter {
Arc::new(builder)
}

pub fn custom_tag(self: Arc<Self>, tag: Alphabet, content: Vec<String>) -> Arc<Self> {
pub fn custom_tag(self: Arc<Self>, tag: Arc<SingleLetterTag>, content: Vec<String>) -> Self {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.custom_tag(tag.into(), content);
Arc::new(builder)
builder.inner = builder.inner.custom_tag(**tag, content);
builder
}

pub fn remove_custom_tag(self: Arc<Self>, tag: Alphabet, content: Vec<String>) -> Arc<Self> {
pub fn remove_custom_tag(
self: Arc<Self>,
tag: Arc<SingleLetterTag>,
content: Vec<String>,
) -> Self {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.remove_custom_tag(tag.into(), content);
Arc::new(builder)
builder.inner = builder.inner.remove_custom_tag(**tag, content);
builder
}

pub fn is_empty(&self) -> bool {
Expand Down
46 changes: 42 additions & 4 deletions bindings/nostr-js/src/message/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,44 @@ impl From<JsAlphabet> for Alphabet {
}
}

#[wasm_bindgen(js_name = SingleLetterTag)]
pub struct JsSingleLetterTag {
inner: SingleLetterTag,
}

impl Deref for JsSingleLetterTag {
type Target = SingleLetterTag;

fn deref(&self) -> &Self::Target {
&self.inner
}
}

#[wasm_bindgen(js_class = SingleLetterTag)]
impl JsSingleLetterTag {
pub fn lowercase(character: JsAlphabet) -> Self {
Self {
inner: SingleLetterTag::lowercase(character.into()),
}
}

pub fn uppercase(character: JsAlphabet) -> Self {
Self {
inner: SingleLetterTag::uppercase(character.into()),
}
}

#[wasm_bindgen(js_name = isLowercase)]
pub fn is_lowercase(&self) -> bool {
self.inner.is_lowercase()
}

#[wasm_bindgen(js_name = isUppercase)]
pub fn is_uppercase(&self) -> bool {
self.inner.is_uppercase()
}
}

#[wasm_bindgen(js_name = SubscriptionId)]
pub struct JsSubscriptionId {
inner: SubscriptionId,
Expand Down Expand Up @@ -253,12 +291,12 @@ impl JsFilter {
}

#[wasm_bindgen(js_name = customTag)]
pub fn custom_tag(self, tag: JsAlphabet, values: Vec<String>) -> Self {
self.inner.custom_tag(tag.into(), values).into()
pub fn custom_tag(self, tag: &JsSingleLetterTag, values: Vec<String>) -> Self {
self.inner.custom_tag(**tag, values).into()
}

#[wasm_bindgen(js_name = removeCustomTag)]
pub fn remove_custom_tag(self, tag: JsAlphabet, values: Vec<String>) -> Self {
self.inner.remove_custom_tag(tag.into(), values).into()
pub fn remove_custom_tag(self, tag: &JsSingleLetterTag, values: Vec<String>) -> Self {
self.inner.remove_custom_tag(**tag, values).into()
}
}
8 changes: 4 additions & 4 deletions crates/nostr-database/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::sync::Arc;
use nostr::event::id;
use nostr::nips::nip01::Coordinate;
use nostr::secp256k1::XOnlyPublicKey;
use nostr::{Alphabet, Event, EventId, Filter, GenericTagValue, Kind, Timestamp};
use nostr::{Alphabet, Event, EventId, Filter, GenericTagValue, Kind, SingleLetterTag, Timestamp};
use thiserror::Error;
use tokio::sync::RwLock;

Expand Down Expand Up @@ -123,7 +123,7 @@ struct FilterIndex {
kinds: HashSet<Kind>,
since: Option<Timestamp>,
until: Option<Timestamp>,
generic_tags: HashMap<Alphabet, HashSet<GenericTagValue>>,
generic_tags: HashMap<SingleLetterTag, HashSet<GenericTagValue>>,
}

impl FilterIndex {
Expand All @@ -143,7 +143,7 @@ impl FilterIndex {
{
let identifier: GenericTagValue = GenericTagValue::String(identifier.into());
self.generic_tags
.entry(Alphabet::D)
.entry(SingleLetterTag::lowercase(Alphabet::D))
.and_modify(|list| {
list.insert(identifier.clone());
})
Expand Down Expand Up @@ -656,7 +656,7 @@ impl DatabaseIndexes {
let kind = kinds.iter().next()?;
let author = authors.iter().next()?;
let identifier = generic_tags
.get(&Alphabet::D)?
.get(&SingleLetterTag::lowercase(Alphabet::D))?
.iter()
.next()
.map(|v| hash(v.to_string()))?;
Expand Down
19 changes: 11 additions & 8 deletions crates/nostr-database/src/tag_indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ use std::ops::{Deref, DerefMut};

use nostr::hashes::siphash24::Hash as SipHash24;
use nostr::hashes::Hash;
use nostr::{Alphabet, GenericTagValue};
use nostr::{Alphabet, GenericTagValue, SingleLetterTag};

/// Tag Index Value Size
pub const TAG_INDEX_VALUE_SIZE: usize = 8;

/// Tag Indexes
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub struct TagIndexes {
inner: BTreeMap<Alphabet, TagIndexValues>,
inner: BTreeMap<SingleLetterTag, TagIndexValues>,
}

impl Deref for TagIndexes {
type Target = BTreeMap<Alphabet, TagIndexValues>;
type Target = BTreeMap<SingleLetterTag, TagIndexValues>;

fn deref(&self) -> &Self::Target {
&self.inner
Expand All @@ -37,7 +37,7 @@ impl DerefMut for TagIndexes {
impl TagIndexes {
/// Get hashed `d` tag
pub fn identifier(&self) -> Option<[u8; TAG_INDEX_VALUE_SIZE]> {
let values = self.inner.get(&Alphabet::D)?;
let values = self.inner.get(&SingleLetterTag::lowercase(Alphabet::D))?;
values.iter().next().copied()
}
}
Expand All @@ -50,21 +50,24 @@ where
fn from(iter: I) -> Self {
let mut tag_index: TagIndexes = TagIndexes::default();
for t in iter.filter(|t| t.len() > 1) {
if let Some(tagnamechar) = single_char_tagname(t[0].as_ref()) {
if let Some(single_letter_tag) = single_char_tagname(t[0].as_ref()) {
let inner = hash(t[1].as_ref());
tag_index.entry(tagnamechar).or_default().insert(inner);
tag_index
.entry(single_letter_tag)
.or_default()
.insert(inner);
}
}
tag_index
}
}

#[inline]
fn single_char_tagname(tagname: &str) -> Option<Alphabet> {
fn single_char_tagname(tagname: &str) -> Option<SingleLetterTag> {
tagname
.chars()
.next()
.and_then(|first| Alphabet::try_from(first).ok())
.and_then(|first| SingleLetterTag::from_char(first).ok())
}

#[inline]
Expand Down
3 changes: 2 additions & 1 deletion crates/nostr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pub use self::event::{
};
pub use self::key::Keys;
pub use self::message::{
Alphabet, ClientMessage, Filter, GenericTagValue, RawRelayMessage, RelayMessage, SubscriptionId,
Alphabet, ClientMessage, Filter, GenericTagValue, RawRelayMessage, RelayMessage,
SingleLetterTag, SubscriptionId,
};
pub use self::nips::nip19::{FromBech32, ToBech32};
pub use self::types::{Contact, Metadata, Timestamp, UncheckedUrl, Url};
Expand Down
2 changes: 1 addition & 1 deletion crates/nostr/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod subscription;

pub use self::client::ClientMessage;
pub use self::relay::{RawRelayMessage, RelayMessage};
pub use self::subscription::{Alphabet, Filter, GenericTagValue, SubscriptionId};
pub use self::subscription::{Alphabet, Filter, GenericTagValue, SingleLetterTag, SubscriptionId};
use crate::event;

/// Messages error
Expand Down
Loading

0 comments on commit 17a5447

Please sign in to comment.