refactor: Move the trait extensions to traits.rs
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
@@ -22,7 +22,8 @@ use crate::{
|
|||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
CommandRunner,
|
CommandRunner,
|
||||||
types::{NaddrOrSet, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
traits::{OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
|
types::NaddrOrSet,
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
nostr_utils::{
|
nostr_utils::{
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ use nostr::{event::Kind, filter::Filter};
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
traits::CommandRunner,
|
traits::{CommandRunner, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
types::{NaddrOrSet, NostrEvent, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
types::{NaddrOrSet, NostrEvent},
|
||||||
},
|
},
|
||||||
error::{N34Error, N34Result},
|
error::{N34Error, N34Result},
|
||||||
nostr_utils::{
|
nostr_utils::{
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ use nostr::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
traits::CommandRunner,
|
traits::{CommandRunner, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
types::{NaddrOrSet, NostrEvent, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
types::{NaddrOrSet, NostrEvent},
|
||||||
},
|
},
|
||||||
error::{N34Error, N34Result},
|
error::{N34Error, N34Result},
|
||||||
nostr_utils::{
|
nostr_utils::{
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ use super::GitPatch;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
traits::CommandRunner,
|
traits::{CommandRunner, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
types::{NaddrOrSet, NostrEvent, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
types::{NaddrOrSet, NostrEvent},
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
nostr_utils::{
|
nostr_utils::{
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ use nostr::{
|
|||||||
|
|
||||||
use super::{CliOptions, CommandRunner};
|
use super::{CliOptions, CommandRunner};
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::types::{NaddrOrSet, NostrEvent, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
cli::{
|
||||||
|
traits::{OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
|
types::{NaddrOrSet, NostrEvent},
|
||||||
|
},
|
||||||
error::{N34Error, N34Result},
|
error::{N34Error, N34Result},
|
||||||
nostr_utils::{
|
nostr_utils::{
|
||||||
NostrClient,
|
NostrClient,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use futures::future;
|
|||||||
use nostr::{event::EventBuilder, key::PublicKey, types::Url};
|
use nostr::{event::EventBuilder, key::PublicKey, types::Url};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::{CliOptions, CommandRunner, NOSTR_ADDRESS_FILE, types::RelayOrSetVecExt},
|
cli::{CliOptions, CommandRunner, NOSTR_ADDRESS_FILE, traits::RelayOrSetVecExt},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
nostr_utils::{NostrClient, traits::NewGitRepositoryAnnouncement, utils},
|
nostr_utils::{NostrClient, traits::NewGitRepositoryAnnouncement, utils},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ use crate::{
|
|||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
CommandRunner,
|
CommandRunner,
|
||||||
types::{NaddrOrSet, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
traits::{OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
|
types::NaddrOrSet,
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
nostr_utils::{NostrClient, traits::NaddrsUtils, utils},
|
nostr_utils::{NostrClient, traits::NaddrsUtils, utils},
|
||||||
|
|||||||
@@ -20,9 +20,8 @@ use crate::{
|
|||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
ConfigError,
|
ConfigError,
|
||||||
MutRepoRelaySetsExt,
|
traits::{CommandRunner, MutRepoRelaySetsExt, NaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
traits::CommandRunner,
|
types::{NaddrOrSet, RelayOrSet},
|
||||||
types::{NaddrOrSet, NaddrOrSetVecExt, RelayOrSet, RelayOrSetVecExt},
|
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ use clap::Args;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
MutRepoRelaySetsExt,
|
traits::{CommandRunner, MutRepoRelaySetsExt, NaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
traits::CommandRunner,
|
types::{NaddrOrSet, RelayOrSet},
|
||||||
types::{NaddrOrSet, NaddrOrSetVecExt, RelayOrSet, RelayOrSetVecExt},
|
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ use clap::Args;
|
|||||||
use nostr::nips::nip19::ToBech32;
|
use nostr::nips::nip19::ToBech32;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::{CliOptions, RepoRelaySet, RepoRelaySetsExt, traits::CommandRunner},
|
cli::{
|
||||||
|
CliOptions,
|
||||||
|
RepoRelaySet,
|
||||||
|
traits::{CommandRunner, RepoRelaySetsExt},
|
||||||
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ use clap::Args;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
CliOptions,
|
CliOptions,
|
||||||
MutRepoRelaySetsExt,
|
traits::{CommandRunner, MutRepoRelaySetsExt, NaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
traits::CommandRunner,
|
types::{NaddrOrSet, RelayOrSet},
|
||||||
types::{NaddrOrSet, NaddrOrSetVecExt, RelayOrSet, RelayOrSetVecExt},
|
|
||||||
},
|
},
|
||||||
error::N34Result,
|
error::N34Result,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use super::{
|
|||||||
types::{NaddrOrSet, NostrEvent},
|
types::{NaddrOrSet, NostrEvent},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::types::{OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
cli::traits::{OptionNaddrOrSetVecExt, RelayOrSetVecExt},
|
||||||
nostr_utils::{NostrClient, traits::NaddrsUtils, utils},
|
nostr_utils::{NostrClient, traits::NaddrsUtils, utils},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ use nostr::{
|
|||||||
types::RelayUrl,
|
types::RelayUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::{N34Error, N34Result};
|
use crate::{
|
||||||
|
cli::traits::{MutRepoRelaySetsExt, RepoRelaySetsExt},
|
||||||
|
error::N34Result,
|
||||||
|
};
|
||||||
|
|
||||||
/// Errors that can occur when working with configuration files.
|
/// Errors that can occur when working with configuration files.
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
@@ -162,139 +165,3 @@ impl RepoRelaySet {
|
|||||||
self.naddrs.retain(|n| seen.insert(n.coordinate.clone()));
|
self.naddrs.retain(|n| seen.insert(n.coordinate.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[easy_ext::ext(MutRepoRelaySetsExt)]
|
|
||||||
impl Vec<RepoRelaySet> {
|
|
||||||
/// Removes duplicate repository addresses from each set.
|
|
||||||
///
|
|
||||||
/// Relays are automatically deduplicated by the HashSet, but
|
|
||||||
/// repository addresses may appear duplicated if relays are sorted
|
|
||||||
/// differently or when relay counts vary. This compares addresses by
|
|
||||||
/// their coordinates, ignoring any embedded relay details.
|
|
||||||
pub fn dedup_naddrs(&mut self) {
|
|
||||||
self.iter_mut().for_each(RepoRelaySet::dedup_naddrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds and returns a mutable reference a set with the given name. Returns
|
|
||||||
/// an error if no set with this name exists.
|
|
||||||
pub fn get_mut_set(&mut self, name: impl AsRef<str>) -> N34Result<&mut RepoRelaySet> {
|
|
||||||
let name = name.as_ref();
|
|
||||||
let set = self
|
|
||||||
.iter_mut()
|
|
||||||
.find(|set| set.name == name)
|
|
||||||
.ok_or_else(|| N34Error::from(ConfigError::SetNotFound(name.to_owned())))?;
|
|
||||||
|
|
||||||
tracing::trace!(
|
|
||||||
name = %name, set = ?set,
|
|
||||||
"Successfully located a set with the giving name"
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates and pushes a new set with the given name.
|
|
||||||
///
|
|
||||||
/// Returns an error if a set with the same name already exists.
|
|
||||||
pub fn push_set(
|
|
||||||
&mut self,
|
|
||||||
name: impl Into<String>,
|
|
||||||
repos: impl IntoIterator<Item = Nip19Coordinate>,
|
|
||||||
relays: impl IntoIterator<Item = RelayUrl>,
|
|
||||||
) -> N34Result<()> {
|
|
||||||
let set_name: String = name.into();
|
|
||||||
tracing::trace!(sets = ?self, "Pushing set '{set_name}' to sets collection");
|
|
||||||
|
|
||||||
if self.as_slice().exists(&set_name) {
|
|
||||||
return Err(ConfigError::SetDuplicateName(set_name).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.push(RepoRelaySet::new(set_name, repos, relays));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the set with the given name if it exists. Returns an error if
|
|
||||||
/// the set is not found.
|
|
||||||
pub fn remove_set(&mut self, name: impl Into<String>) -> N34Result<()> {
|
|
||||||
let set_name: String = name.into();
|
|
||||||
tracing::trace!(set_name, sets = ?self, "Removing set '{set_name}' from sets collection");
|
|
||||||
|
|
||||||
if !self.as_slice().exists(&set_name) {
|
|
||||||
return Err(ConfigError::SetNotFound(set_name).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.retain(|s| s.name != set_name);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the given relays from the specified set.
|
|
||||||
pub fn remove_relays(
|
|
||||||
&mut self,
|
|
||||||
name: impl Into<String>,
|
|
||||||
relays: impl Iterator<Item = RelayUrl>,
|
|
||||||
) -> N34Result<()> {
|
|
||||||
let relays = Vec::from_iter(relays);
|
|
||||||
let set = self.get_mut_set(name.into())?;
|
|
||||||
|
|
||||||
set.relays.retain(|r| !relays.contains(r));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the given naddrs from the specified set.
|
|
||||||
pub fn remove_naddrs(
|
|
||||||
&mut self,
|
|
||||||
name: impl Into<String>,
|
|
||||||
naddrs: impl Iterator<Item = Nip19Coordinate>,
|
|
||||||
) -> N34Result<()> {
|
|
||||||
let coordinates = Vec::from_iter(naddrs.map(|n| n.coordinate));
|
|
||||||
let set = self.get_mut_set(name.into())?;
|
|
||||||
|
|
||||||
set.naddrs.retain(|n| !coordinates.contains(&n.coordinate));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[easy_ext::ext(RepoRelaySetsExt)]
|
|
||||||
impl &[RepoRelaySet] {
|
|
||||||
/// Checks for duplicate set names. Returns an error if any duplicates are
|
|
||||||
/// found.
|
|
||||||
pub fn ensure_names(&self) -> N34Result<()> {
|
|
||||||
let mut names = Vec::with_capacity(self.len());
|
|
||||||
names.extend(self.iter().map(|s| s.name.to_owned()));
|
|
||||||
|
|
||||||
names.sort_unstable();
|
|
||||||
|
|
||||||
if let Some(duplicate) = duplicate_in_sorted(&names) {
|
|
||||||
return Err(ConfigError::SetDuplicateName(duplicate.clone()).into());
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a set with the given name exists.
|
|
||||||
pub fn exists(&self, set_name: &str) -> bool {
|
|
||||||
self.iter().any(|set| set.name == set_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds and returns a reference a set with the given name. Returns an
|
|
||||||
/// error if no set with this name exists.
|
|
||||||
pub fn get_set(&self, name: impl AsRef<str>) -> N34Result<&RepoRelaySet> {
|
|
||||||
let name = name.as_ref();
|
|
||||||
let set = self
|
|
||||||
.iter()
|
|
||||||
.find(|set| set.name == name)
|
|
||||||
.ok_or_else(|| N34Error::from(ConfigError::SetNotFound(name.to_owned())))?;
|
|
||||||
tracing::trace!(
|
|
||||||
name = %name, set = ?set,
|
|
||||||
"Successfully located a set with the giving name"
|
|
||||||
);
|
|
||||||
Ok(set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper function that checks for duplicates in a sorted slice
|
|
||||||
fn duplicate_in_sorted<T: PartialEq + Clone>(items: &[T]) -> Option<&T> {
|
|
||||||
items.windows(2).find(|w| w[0] == w[1]).map(|w| &w[0])
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,10 +14,17 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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>.
|
// along with this program. If not, see <https://gnu.org/licenses/gpl-3.0.html>.
|
||||||
|
|
||||||
use nostr::event::EventId;
|
use nostr::{event::EventId, nips::nip19::Nip19Coordinate, types::RelayUrl};
|
||||||
|
|
||||||
use super::CliOptions;
|
use super::CliOptions;
|
||||||
use crate::{cli::types::NostrEvent, error::N34Result};
|
use crate::{
|
||||||
|
cli::{
|
||||||
|
ConfigError,
|
||||||
|
RepoRelaySet,
|
||||||
|
types::{NaddrOrSet, NostrEvent, RelayOrSet},
|
||||||
|
},
|
||||||
|
error::{N34Error, N34Result},
|
||||||
|
};
|
||||||
|
|
||||||
/// A trait defining the interface for command runners in the CLI.
|
/// A trait defining the interface for command runners in the CLI.
|
||||||
pub trait CommandRunner {
|
pub trait CommandRunner {
|
||||||
@@ -40,3 +47,180 @@ impl Vec<NostrEvent> {
|
|||||||
self.into_iter().map(|e| e.event_id).collect()
|
self.into_iter().map(|e| e.event_id).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[easy_ext::ext(NaddrOrSetVecExt)]
|
||||||
|
impl Vec<NaddrOrSet> {
|
||||||
|
/// Converts this vector of [`NaddrOrSet`] into a flat vector of
|
||||||
|
/// [`Nip19Coordinate`] using the given sets.
|
||||||
|
pub fn flat_naddrs(self, sets: &[RepoRelaySet]) -> N34Result<Vec<Nip19Coordinate>> {
|
||||||
|
self.into_iter()
|
||||||
|
.map(|n| n.get_naddrs(sets))
|
||||||
|
.try_fold(Vec::new(), |mut acc, item| {
|
||||||
|
acc.extend(item?);
|
||||||
|
Ok(acc)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[easy_ext::ext(RelayOrSetVecExt)]
|
||||||
|
impl Vec<RelayOrSet> {
|
||||||
|
/// Converts this vector of [`RelayOrSet`] into a flat vector of
|
||||||
|
/// [`RelayUrl`] using the given sets.
|
||||||
|
pub fn flat_relays(self, sets: &[RepoRelaySet]) -> N34Result<Vec<RelayUrl>> {
|
||||||
|
self.into_iter()
|
||||||
|
.map(|n| n.get_relays(sets))
|
||||||
|
.try_fold(Vec::new(), |mut acc, item| {
|
||||||
|
acc.extend(item?);
|
||||||
|
Ok(acc)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[easy_ext::ext(OptionNaddrOrSetVecExt)]
|
||||||
|
impl Option<Vec<NaddrOrSet>> {
|
||||||
|
/// Converts this vector of [`NaddrOrSet`] into a flat vector of
|
||||||
|
/// [`Nip19Coordinate`] using the given sets.
|
||||||
|
pub fn flat_naddrs(&self, sets: &[RepoRelaySet]) -> N34Result<Option<Vec<Nip19Coordinate>>> {
|
||||||
|
// Clones self here to simplify command code
|
||||||
|
self.clone()
|
||||||
|
.map(|naddrs| naddrs.flat_naddrs(sets))
|
||||||
|
.transpose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[easy_ext::ext(MutRepoRelaySetsExt)]
|
||||||
|
impl Vec<RepoRelaySet> {
|
||||||
|
/// Removes duplicate repository addresses from each set.
|
||||||
|
///
|
||||||
|
/// Relays are automatically deduplicated by the HashSet, but
|
||||||
|
/// repository addresses may appear duplicated if relays are sorted
|
||||||
|
/// differently or when relay counts vary. This compares addresses by
|
||||||
|
/// their coordinates, ignoring any embedded relay details.
|
||||||
|
pub fn dedup_naddrs(&mut self) {
|
||||||
|
self.iter_mut().for_each(RepoRelaySet::dedup_naddrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds and returns a mutable reference a set with the given name. Returns
|
||||||
|
/// an error if no set with this name exists.
|
||||||
|
pub fn get_mut_set(&mut self, name: impl AsRef<str>) -> N34Result<&mut RepoRelaySet> {
|
||||||
|
let name = name.as_ref();
|
||||||
|
let set = self
|
||||||
|
.iter_mut()
|
||||||
|
.find(|set| set.name == name)
|
||||||
|
.ok_or_else(|| N34Error::from(ConfigError::SetNotFound(name.to_owned())))?;
|
||||||
|
|
||||||
|
tracing::trace!(
|
||||||
|
name = %name, set = ?set,
|
||||||
|
"Successfully located a set with the giving name"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates and pushes a new set with the given name.
|
||||||
|
///
|
||||||
|
/// Returns an error if a set with the same name already exists.
|
||||||
|
pub fn push_set(
|
||||||
|
&mut self,
|
||||||
|
name: impl Into<String>,
|
||||||
|
repos: impl IntoIterator<Item = Nip19Coordinate>,
|
||||||
|
relays: impl IntoIterator<Item = RelayUrl>,
|
||||||
|
) -> N34Result<()> {
|
||||||
|
let set_name: String = name.into();
|
||||||
|
tracing::trace!(sets = ?self, "Pushing set '{set_name}' to sets collection");
|
||||||
|
|
||||||
|
if self.as_slice().exists(&set_name) {
|
||||||
|
return Err(ConfigError::SetDuplicateName(set_name).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.push(RepoRelaySet::new(set_name, repos, relays));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the set with the given name if it exists. Returns an error if
|
||||||
|
/// the set is not found.
|
||||||
|
pub fn remove_set(&mut self, name: impl Into<String>) -> N34Result<()> {
|
||||||
|
let set_name: String = name.into();
|
||||||
|
tracing::trace!(set_name, sets = ?self, "Removing set '{set_name}' from sets collection");
|
||||||
|
|
||||||
|
if !self.as_slice().exists(&set_name) {
|
||||||
|
return Err(ConfigError::SetNotFound(set_name).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.retain(|s| s.name != set_name);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the given relays from the specified set.
|
||||||
|
pub fn remove_relays(
|
||||||
|
&mut self,
|
||||||
|
name: impl Into<String>,
|
||||||
|
relays: impl Iterator<Item = RelayUrl>,
|
||||||
|
) -> N34Result<()> {
|
||||||
|
let relays = Vec::from_iter(relays);
|
||||||
|
let set = self.get_mut_set(name.into())?;
|
||||||
|
|
||||||
|
set.relays.retain(|r| !relays.contains(r));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the given naddrs from the specified set.
|
||||||
|
pub fn remove_naddrs(
|
||||||
|
&mut self,
|
||||||
|
name: impl Into<String>,
|
||||||
|
naddrs: impl Iterator<Item = Nip19Coordinate>,
|
||||||
|
) -> N34Result<()> {
|
||||||
|
let coordinates = Vec::from_iter(naddrs.map(|n| n.coordinate));
|
||||||
|
let set = self.get_mut_set(name.into())?;
|
||||||
|
|
||||||
|
set.naddrs.retain(|n| !coordinates.contains(&n.coordinate));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[easy_ext::ext(RepoRelaySetsExt)]
|
||||||
|
impl &[RepoRelaySet] {
|
||||||
|
/// Checks for duplicate set names. Returns an error if any duplicates are
|
||||||
|
/// found.
|
||||||
|
pub fn ensure_names(&self) -> N34Result<()> {
|
||||||
|
let mut names = Vec::with_capacity(self.len());
|
||||||
|
names.extend(self.iter().map(|s| s.name.to_owned()));
|
||||||
|
|
||||||
|
names.sort_unstable();
|
||||||
|
|
||||||
|
if let Some(duplicate) = duplicate_in_sorted(&names) {
|
||||||
|
return Err(ConfigError::SetDuplicateName(duplicate.clone()).into());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if a set with the given name exists.
|
||||||
|
pub fn exists(&self, set_name: &str) -> bool {
|
||||||
|
self.iter().any(|set| set.name == set_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds and returns a reference a set with the given name. Returns an
|
||||||
|
/// error if no set with this name exists.
|
||||||
|
pub fn get_set(&self, name: impl AsRef<str>) -> N34Result<&RepoRelaySet> {
|
||||||
|
let name = name.as_ref();
|
||||||
|
let set = self
|
||||||
|
.iter()
|
||||||
|
.find(|set| set.name == name)
|
||||||
|
.ok_or_else(|| N34Error::from(ConfigError::SetNotFound(name.to_owned())))?;
|
||||||
|
tracing::trace!(
|
||||||
|
name = %name, set = ?set,
|
||||||
|
"Successfully located a set with the giving name"
|
||||||
|
);
|
||||||
|
Ok(set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function that checks for duplicates in a sorted slice
|
||||||
|
fn duplicate_in_sorted<T: PartialEq + Clone>(items: &[T]) -> Option<&T> {
|
||||||
|
items.windows(2).find(|w| w[0] == w[1]).map(|w| &w[0])
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ use nostr::{
|
|||||||
use nostr_connect::client::AuthUrlHandler;
|
use nostr_connect::client::AuthUrlHandler;
|
||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
|
|
||||||
use super::{RepoRelaySetsExt, parsers};
|
use super::parsers;
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::RepoRelaySet,
|
cli::{RepoRelaySet, traits::RepoRelaySetsExt},
|
||||||
error::{N34Error, N34Result},
|
error::{N34Error, N34Result},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,47 +191,6 @@ impl FromStr for NostrEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[easy_ext::ext(NaddrOrSetVecExt)]
|
|
||||||
impl Vec<NaddrOrSet> {
|
|
||||||
/// Converts this vector of [`NaddrOrSet`] into a flat vector of
|
|
||||||
/// [`Nip19Coordinate`] using the given sets.
|
|
||||||
pub fn flat_naddrs(self, sets: &[RepoRelaySet]) -> N34Result<Vec<Nip19Coordinate>> {
|
|
||||||
self.into_iter()
|
|
||||||
.map(|n| n.get_naddrs(sets))
|
|
||||||
.try_fold(Vec::new(), |mut acc, item| {
|
|
||||||
acc.extend(item?);
|
|
||||||
Ok(acc)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[easy_ext::ext(RelayOrSetVecExt)]
|
|
||||||
impl Vec<RelayOrSet> {
|
|
||||||
/// Converts this vector of [`RelayOrSet`] into a flat vector of
|
|
||||||
/// [`RelayUrl`] using the given sets.
|
|
||||||
pub fn flat_relays(self, sets: &[RepoRelaySet]) -> N34Result<Vec<RelayUrl>> {
|
|
||||||
self.into_iter()
|
|
||||||
.map(|n| n.get_relays(sets))
|
|
||||||
.try_fold(Vec::new(), |mut acc, item| {
|
|
||||||
acc.extend(item?);
|
|
||||||
Ok(acc)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[easy_ext::ext(OptionNaddrOrSetVecExt)]
|
|
||||||
impl Option<Vec<NaddrOrSet>> {
|
|
||||||
/// Converts this vector of [`NaddrOrSet`] into a flat vector of
|
|
||||||
/// [`Nip19Coordinate`] using the given sets.
|
|
||||||
pub fn flat_naddrs(&self, sets: &[RepoRelaySet]) -> N34Result<Option<Vec<Nip19Coordinate>>> {
|
|
||||||
// Clones self here to simplify command code
|
|
||||||
self.clone()
|
|
||||||
.map(|naddrs| naddrs.flat_naddrs(sets))
|
|
||||||
.transpose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<NaddrOrSet, String> {
|
fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<NaddrOrSet, String> {
|
||||||
let (username, domain) = nip5.split_once("@").unwrap_or(("_", nip5));
|
let (username, domain) = nip5.split_once("@").unwrap_or(("_", nip5));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user