This commit is contained in:
2026-08-08 17:08:20 +07:00
parent 5ba437ed48
commit e36d96bf50
2 changed files with 27 additions and 30 deletions
+22 -27
View File
@@ -4,18 +4,18 @@ use nostr::prelude::*;
/// Parsed NIP-34 repository announcement (plain data, ready for the UI).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Announcement {
/// Repository ID (`d` tag).
pub id: String,
/// Author of the announcement event.
pub owner: PublicKey,
/// When the announcement was published (for latest-wins resolution).
pub created_at: Timestamp,
/// Repository ID (`d` tag).
pub id: String,
pub name: Option<SharedString>,
pub description: Option<SharedString>,
/// Webpage URLs for browsing.
pub web: Vec<String>,
pub web: Vec<Url>,
/// URLs for `git clone`.
pub clone: Vec<String>,
pub clone: Vec<Url>,
/// Relays the repository monitors for patches and issues.
pub relays: Vec<RelayUrl>,
/// Earliest unique commit ID (`r` tag with `euc` marker).
@@ -33,36 +33,25 @@ impl Announcement {
return None;
}
let mut id: Option<String> = None;
let id = event.tags.identifier()?;
let mut hashtags: Vec<String> = Vec::new();
hashtags.extend(event.tags.hashtags().map(|t| t.to_string()));
let mut name: Option<SharedString> = None;
let mut description: Option<SharedString> = None;
let mut web: Vec<String> = Vec::new();
let mut clone: Vec<String> = Vec::new();
let mut web: Vec<Url> = Vec::new();
let mut clone: Vec<Url> = Vec::new();
let mut relays: Vec<RelayUrl> = Vec::new();
let mut euc: Option<String> = None;
let mut maintainers: Vec<PublicKey> = Vec::new();
let mut hashtags: Vec<String> = Vec::new();
for tag in event.tags.iter() {
// The `d` and `t` tags aren't part of the NIP-34 tag codec; parse them directly.
if tag.kind() == "d" {
id = tag.content().map(str::to_owned);
continue;
}
if tag.kind() == "t" {
if let Some(value) = tag.content() {
hashtags.push(value.to_owned());
}
continue;
}
match Nip34Tag::parse(tag.as_slice()) {
Ok(Nip34Tag::Name(value)) => name = Some(value.into()),
Ok(Nip34Tag::Description(value)) => description = Some(value.into()),
Ok(Nip34Tag::Web(urls)) => web.extend(urls.into_iter().map(|url| url.to_string())),
Ok(Nip34Tag::Clone(urls)) => {
clone.extend(urls.into_iter().map(|url| url.to_string()))
}
Ok(Nip34Tag::Web(urls)) => web.extend(urls),
Ok(Nip34Tag::Clone(urls)) => clone.extend(urls),
Ok(Nip34Tag::Relays(urls)) => relays.extend(urls),
Ok(Nip34Tag::EarliestUniqueCommitId(commit)) => euc = Some(commit.to_string()),
Ok(Nip34Tag::Maintainers(keys)) => maintainers.extend(keys),
@@ -73,7 +62,7 @@ impl Announcement {
Some(Self {
owner: event.pubkey,
created_at: event.created_at,
id: id?,
id,
name,
description,
web,
@@ -141,8 +130,14 @@ mod tests {
announcement.description.as_deref(),
Some("A test repository")
);
assert_eq!(announcement.web, vec!["https://example.com/repo"]);
assert_eq!(announcement.clone, vec!["https://example.com/repo.git"]);
assert_eq!(
announcement.web,
vec![Url::parse("https://example.com/repo").unwrap()]
);
assert_eq!(
announcement.clone,
vec![Url::parse("https://example.com/repo.git").unwrap()]
);
assert_eq!(
announcement.relays,
vec![RelayUrl::parse("wss://relay.example.com").unwrap()]