From b9a88672b8734448615354e3f46748d2fdc2f647 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sun, 1 Oct 2023 00:00:00 +0100 Subject: feat(prs-create) send commit to relay - add client - use client to send event - add async functionality - enabler for relay interaction whilst getting cli input --- src/client.rs | 65 ++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 6 ++-- src/sub_commands/prs/create.rs | 20 ++++++++++++- src/sub_commands/prs/mod.rs | 4 +-- 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/client.rs (limited to 'src') diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..a6f7dda --- /dev/null +++ b/src/client.rs @@ -0,0 +1,65 @@ +// have you considered + +// TO USE ASYNC + +// in traits (required for mocking unit tests) +// https://rust-lang.github.io/async-book/07_workarounds/05_async_in_traits.html +// https://github.com/dtolnay/async-trait +// see https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-trait-nightly.html +// I think we can use the async-trait crate and switch to the native feature +// which is currently in nightly. alternatively we can use nightly as it looks +// certain that the implementation is going to make it to stable but we don't +// want to inadvertlty use other features of nightly that might be removed. +use anyhow::Result; +use async_trait::async_trait; +#[cfg(test)] +use mockall::*; +use nostr::Event; + +pub struct Client { + client: nostr_sdk::Client, +} + +#[async_trait] +#[cfg_attr(test, automock)] +pub trait Connect { + fn default() -> Self; + fn new(opts: Params) -> Self; + async fn connect(&self) -> Result<()>; + async fn send_event_to(&self, url: &str, event: nostr::event::Event) -> Result; +} + +#[async_trait] +impl Connect for Client { + fn default() -> Self { + Client { + client: nostr_sdk::Client::new(&nostr::Keys::generate()), + } + } + fn new(opts: Params) -> Self { + Client { + client: nostr_sdk::Client::new(&opts.keys.unwrap_or(nostr::Keys::generate())), + } + } + async fn connect(&self) -> Result<()> { + self.client.add_relay("ws://localhost:8080", None).await?; + self.client.connect().await; + // self.client.s + Ok(()) + } + async fn send_event_to(&self, url: &str, event: Event) -> Result { + Ok(self.client.send_event_to(url, event).await?) + } +} + +#[derive(Default)] +pub struct Params { + pub keys: Option, +} + +impl Params { + pub fn with_keys(mut self, keys: nostr::Keys) -> Self { + self.keys = Some(keys); + self + } +} diff --git a/src/main.rs b/src/main.rs index 5094c11..9c37aa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use anyhow::Result; use clap::{Parser, Subcommand}; mod cli_interactor; +mod client; mod config; mod git; mod key_handling; @@ -33,10 +34,11 @@ enum Commands { Prs(sub_commands::prs::SubCommandArgs), } -fn main() -> Result<()> { +#[tokio::main] +async fn main() -> Result<()> { let cli = Cli::parse(); match &cli.command { Commands::Login(args) => sub_commands::login::launch(&cli, args), - Commands::Prs(args) => sub_commands::prs::launch(&cli, args), + Commands::Prs(args) => futures::executor::block_on(sub_commands::prs::launch(&cli, args)), } } diff --git a/src/sub_commands/prs/create.rs b/src/sub_commands/prs/create.rs index dd32c65..89ea652 100644 --- a/src/sub_commands/prs/create.rs +++ b/src/sub_commands/prs/create.rs @@ -3,6 +3,7 @@ use nostr::{prelude::sha1::Hash as Sha1Hash, EventBuilder, Marker, Tag, TagKind} use crate::{ cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms}, + client::{Client, Connect, Params as ClientParams}, git::{Repo, RepoActions}, login, Cli, }; @@ -23,7 +24,7 @@ pub struct SubCommandArgs { to_branch: Option, } -pub fn launch( +pub async fn launch( cli_args: &Cli, _pr_args: &super::SubCommandArgs, args: &SubCommandArgs, @@ -81,6 +82,7 @@ pub fn launch( let root_commit = git_repo .get_root_commit(to_branch.as_str()) .context("failed to get root commit of the repository")?; + // create PR event let keys = login::launch(&cli_args.nsec, &cli_args.password)?; @@ -138,7 +140,23 @@ pub fn launch( ); } + let client = Client::new(ClientParams::default().with_keys(keys)); + + println!("connecting..."); + client.connect().await?; + println!("connected..."); + // TODO check if there is already a similarly named PR + let _ = client + .send_event_to("ws://localhost:8080", pr_event) + .await?; + // TODO post each PR + // TODO report + println!("posted successfully to 4/5 of your relays and 0/4 of maintainers relays"); + // should we have a relays in Repository event? + // yes + // + // TODO connect to relays and post Ok(()) diff --git a/src/sub_commands/prs/mod.rs b/src/sub_commands/prs/mod.rs index c316e73..982e866 100644 --- a/src/sub_commands/prs/mod.rs +++ b/src/sub_commands/prs/mod.rs @@ -15,8 +15,8 @@ pub enum Commands { Create(create::SubCommandArgs), } -pub fn launch(cli_args: &Cli, pr_args: &SubCommandArgs) -> Result<()> { +pub async fn launch(cli_args: &Cli, pr_args: &SubCommandArgs) -> Result<()> { match &pr_args.prs_command { - Commands::Create(args) => create::launch(cli_args, pr_args, args), + Commands::Create(args) => create::launch(cli_args, pr_args, args).await, } } -- cgit v1.2.3