From 57321aa9136293b24757a6695a5c92087af539ab Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 1 Nov 2023 00:00:00 +0000 Subject: feat(prs-create) send to repo relays fetch repository reference events to identify repository relays send pr events to repository relays alongside user relays --- src/repo_ref.rs | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 2 deletions(-) (limited to 'src/repo_ref.rs') diff --git a/src/repo_ref.rs b/src/repo_ref.rs index 3b0b1b4..a92b5b3 100644 --- a/src/repo_ref.rs +++ b/src/repo_ref.rs @@ -1,6 +1,12 @@ -use anyhow::{Context, Result}; +use anyhow::{bail, Context, Result}; use nostr::Tag; +#[cfg(not(test))] +use crate::client::Client; +use crate::client::Connect; +#[cfg(test)] +use crate::client::MockConnect; + #[derive(Default)] pub struct RepoRef { pub name: String, @@ -12,10 +18,43 @@ pub struct RepoRef { // code languages and hashtags } +impl TryFrom for RepoRef { + type Error = anyhow::Error; + + fn try_from(event: nostr::Event) -> Result { + if !event.kind.as_u64().eq(&REPO_REF_KIND) { + bail!("incorrect kind"); + } + let mut r = Self::default(); + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("name")) { + r.name = t.as_vec()[1].clone(); + } + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("description")) { + r.description = t.as_vec()[1].clone(); + } + + if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("d")) { + r.root_commit = t.as_vec()[1].clone(); + } + + r.relays = event + .tags + .iter() + .filter(|t| t.as_vec()[0].eq("relay")) + .map(|t| t.as_vec()[1].clone()) + .collect(); + + Ok(r) + } +} +static REPO_REF_KIND: u64 = 300_317; + impl RepoRef { pub fn to_event(&self, keys: &nostr::Keys) -> Result { nostr_sdk::EventBuilder::new( - nostr::event::Kind::Custom(30017), + nostr::event::Kind::Custom(REPO_REF_KIND), "", &[ vec![ @@ -36,6 +75,36 @@ impl RepoRef { } } +pub async fn fetch( + root_commit: String, + #[cfg(test)] client: &MockConnect, + #[cfg(not(test))] client: &Client, + // TODO: more rubust way of finding repo events + relays: Vec, +) -> Result { + // TODO: fetch relay information from file + + let events: Vec = client + .get_events( + relays, + vec![ + nostr::Filter::default() + .kind(nostr::Kind::Custom(REPO_REF_KIND)) + .identifier(root_commit), + ], + ) + .await?; + + RepoRef::try_from( + events + .iter() + .filter(|e| e.kind.as_u64() == REPO_REF_KIND) + .max_by_key(|e| e.created_at) + .context("cannot find repository reference event")? + .clone(), + ) +} + #[cfg(test)] mod tests { use test_utils::*; @@ -52,6 +121,38 @@ mod tests { .to_event(&TEST_KEY_1_KEYS) .unwrap() } + mod try_from { + use super::*; + + #[test] + fn name() { + assert_eq!(RepoRef::try_from(create()).unwrap().name, "test name",) + } + + #[test] + fn description() { + assert_eq!( + RepoRef::try_from(create()).unwrap().description, + "test description", + ) + } + + #[test] + fn root_commit() { + assert_eq!( + RepoRef::try_from(create()).unwrap().root_commit, + "23471389461", + ) + } + + #[test] + fn relays() { + assert_eq!( + RepoRef::try_from(create()).unwrap().relays, + vec!["ws://relay1.io".to_string(), "ws://relay2.io".to_string()], + ) + } + } mod to_event { use super::*; -- cgit v1.2.3