chore: Move NostrEvent to crate::cli::types

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb
2025-06-03 09:27:20 +00:00
parent 08505151bd
commit 57fc868b63
2 changed files with 63 additions and 60 deletions

View File

@@ -14,16 +14,16 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://gnu.org/licenses/gpl-3.0.html>.
use std::{fs, str::FromStr};
use std::fs;
use clap::{ArgGroup, Args};
use futures::future;
use nostr::{
event::{Event, EventBuilder, EventId, Kind},
event::{Event, EventBuilder, Kind},
filter::Filter,
nips::{
nip01::{Coordinate, Metadata},
nip19::{self, FromBech32, ToBech32},
nip19::ToBech32,
},
types::RelayUrl,
};
@@ -32,7 +32,7 @@ use super::{CliOptions, CommandRunner};
use crate::{
cli::{
CliConfig,
types::{NaddrOrSet, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
types::{NaddrOrSet, NostrEvent, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
},
error::{N34Error, N34Result},
nostr_utils::{
@@ -47,43 +47,6 @@ const NPUB_LEN: usize = 63;
/// The max date "9999-01-01 at 00:00 UTC"
const MAX_DATE: i64 = 253370764800;
/// Parses and represents a Nostr `nevent1` or `note1`.
#[derive(Debug, Clone)]
struct NostrEvent {
/// Unique identifier for the event.
event_id: EventId,
/// List of relay URLs associated with the event. Empty if parsing a
/// `note1`.
relays: Vec<RelayUrl>,
}
impl NostrEvent {
/// Create a new [`NostrEvent`] instance
fn new(event_id: EventId, relays: Vec<RelayUrl>) -> Self {
Self { event_id, relays }
}
}
impl FromStr for NostrEvent {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let str_event = s.trim().trim_start_matches("nostr:");
if str_event.starts_with("nevent1") {
let event = nip19::Nip19Event::from_bech32(str_event).map_err(|e| e.to_string())?;
Ok(Self::new(event.event_id, event.relays))
} else if str_event.starts_with("note1") {
Ok(Self::new(
EventId::from_bech32(str_event).map_err(|e| e.to_string())?,
Vec::new(),
))
} else {
Err("Invalid event id, must starts with `note1` or `nevent1`".to_owned())
}
}
}
/// Arguments for the `reply` command
#[derive(Args, Debug)]
#[clap(

View File

@@ -17,8 +17,12 @@
use std::str::FromStr;
use nostr::{
event::Kind,
nips::{self, nip01::Coordinate, nip19::Nip19Coordinate},
event::{EventId, Kind},
nips::{
self,
nip01::Coordinate,
nip19::{self, FromBech32, Nip19Coordinate},
},
types::RelayUrl,
};
use tokio::runtime::Handle;
@@ -47,6 +51,16 @@ pub enum RelayOrSet {
Set(String),
}
/// Parses and represents a Nostr `nevent1` or `note1`.
#[derive(Debug, Clone)]
pub struct NostrEvent {
/// Unique identifier for the event.
pub event_id: EventId,
/// List of relay URLs associated with the event. Empty if parsing a
/// `note1`.
pub relays: Vec<RelayUrl>,
}
impl NaddrOrSet {
/// Returns the naddr if `Naddr` or try to get the relays from the set.
/// Returns error if the set naddrs are empty or the set not found.
@@ -86,6 +100,13 @@ impl RelayOrSet {
}
}
impl NostrEvent {
/// Create a new [`NostrEvent`] instance
fn new(event_id: EventId, relays: Vec<RelayUrl>) -> Self {
Self { event_id, relays }
}
}
impl FromStr for NaddrOrSet {
type Err = String;
@@ -132,24 +153,23 @@ impl FromStr for RelayOrSet {
}
}
fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<NaddrOrSet, String> {
let (username, domain) = nip5.split_once("@").unwrap_or(("_", nip5));
impl FromStr for NostrEvent {
type Err = String;
let nip5_profile = tokio::task::block_in_place(|| {
Handle::current().block_on(async {
nips::nip05::profile(format!("{username}@{domain}"), None)
.await
.map_err(|err| err.to_string())
})
})?;
Ok(NaddrOrSet::Naddr(
Nip19Coordinate::new(
Coordinate::new(Kind::GitRepoAnnouncement, nip5_profile.public_key).identifier(repo_id),
nip5_profile.relays,
)
.expect("The relays is `RelayUrl`"),
))
fn from_str(s: &str) -> Result<Self, Self::Err> {
let str_event = s.trim().trim_start_matches("nostr:");
if str_event.starts_with("nevent1") {
let event = nip19::Nip19Event::from_bech32(str_event).map_err(|e| e.to_string())?;
Ok(Self::new(event.event_id, event.relays))
} else if str_event.starts_with("note1") {
Ok(Self::new(
EventId::from_bech32(str_event).map_err(|e| e.to_string())?,
Vec::new(),
))
} else {
Err("Invalid event id, must starts with `note1` or `nevent1`".to_owned())
}
}
}
#[easy_ext::ext(NaddrOrSetVecExt)]
@@ -192,3 +212,23 @@ impl Option<Vec<NaddrOrSet>> {
.transpose()
}
}
fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<NaddrOrSet, String> {
let (username, domain) = nip5.split_once("@").unwrap_or(("_", nip5));
let nip5_profile = tokio::task::block_in_place(|| {
Handle::current().block_on(async {
nips::nip05::profile(format!("{username}@{domain}"), None)
.await
.map_err(|err| err.to_string())
})
})?;
Ok(NaddrOrSet::Naddr(
Nip19Coordinate::new(
Coordinate::new(Kind::GitRepoAnnouncement, nip5_profile.public_key).identifier(repo_id),
nip5_profile.relays,
)
.expect("The relays is `RelayUrl`"),
))
}