Skip to content

Commit

Permalink
Merge branch 'master' into add-doc-auto-cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
umgefahren authored Aug 2, 2024
2 parents 0e26e28 + 40eb356 commit ae4b0a8
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.18.1

- Add `with_p2p` on `Multiaddr`. See [PR 102].

[PR 102]: https://github.com/multiformats/rust-multiaddr/pull/102

# 0.18.0

- Add `WebTransport` instance for `Multiaddr`. See [PR 70].
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ authors = ["dignifiedquire <dignifiedquire@gmail.com>", "Parity Technologies <ad
description = "Implementation of the multiaddr format"
edition = "2021"
rust-version = "1.59.0"
homepage = "https://github.com/multiformats/rust-multiaddr"
repository = "https://github.com/multiformats/rust-multiaddr"
keywords = ["multiaddr", "ipfs"]
license = "MIT"
name = "multiaddr"
readme = "README.md"
version = "0.18.0"
version = "0.18.1"

[features]
default = ["url"]
Expand Down
18 changes: 16 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ use std::{
sync::Arc,
};

use libp2p_identity::PeerId;

#[cfg(feature = "url")]
pub use self::from_url::{from_url, from_url_lossy, FromUrlErr};

Expand Down Expand Up @@ -128,6 +130,18 @@ impl Multiaddr {
self
}

/// Appends the given [`PeerId`] if not yet present at the end of this multiaddress.
///
/// Fails if this address ends in a _different_ [`PeerId`].
/// In that case, the original, unmodified address is returned.
pub fn with_p2p(self, peer: PeerId) -> std::result::Result<Self, Self> {
match self.iter().last() {
Some(Protocol::P2p(p)) if p == peer => Ok(self),
Some(Protocol::P2p(_)) => Err(self),
_ => Ok(self.with(Protocol::P2p(peer))),
}
}

/// Returns the components of this multiaddress.
///
/// # Example
Expand Down Expand Up @@ -204,7 +218,7 @@ impl Multiaddr {

impl fmt::Debug for Multiaddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.to_string().fmt(f)
fmt::Display::fmt(self, f)
}
}

Expand All @@ -222,7 +236,7 @@ impl fmt::Display for Multiaddr {
///
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for s in self.iter() {
s.to_string().fmt(f)?;
s.fmt(f)?;
}
Ok(())
}
Expand Down
63 changes: 63 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,3 +661,66 @@ fn arbitrary_impl_for_all_proto_variants() {
let variants = core::mem::variant_count::<Protocol>() as u8;
assert_eq!(variants, Proto::IMPL_VARIANT_COUNT);
}

mod multiaddr_with_p2p {
use libp2p_identity::PeerId;
use multiaddr::Multiaddr;

fn test_multiaddr_with_p2p(
multiaddr: &str,
peer: &str,
expected: std::result::Result<&str, &str>,
) {
let peer = peer.parse::<PeerId>().unwrap();
let expected = expected
.map(|a| a.parse::<Multiaddr>().unwrap())
.map_err(|a| a.parse::<Multiaddr>().unwrap());

let mut multiaddr = multiaddr.parse::<Multiaddr>().unwrap();
// Testing multiple time to validate idempotence.
for _ in 0..3 {
let result = multiaddr.with_p2p(peer);
assert_eq!(result, expected);
multiaddr = result.unwrap_or_else(|addr| addr);
}
}

#[test]
fn empty_multiaddr() {
// Multiaddr is empty -> it should push and return Ok.
test_multiaddr_with_p2p(
"",
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
Ok("/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
)
}
#[test]
fn non_p2p_terminated() {
// Last protocol is not p2p -> it should push and return Ok.
test_multiaddr_with_p2p(
"/ip4/127.0.0.1",
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
Ok("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
)
}

#[test]
fn p2p_terminated_same_peer() {
// Last protocol is p2p and the contained peer matches the provided one -> it should do nothing and return Ok.
test_multiaddr_with_p2p(
"/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
Ok("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
)
}

#[test]
fn p2p_terminated_different_peer() {
// Last protocol is p2p but the contained peer does not match the provided one -> it should do nothing and return Err.
test_multiaddr_with_p2p(
"/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
Err("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
)
}
}

0 comments on commit ae4b0a8

Please sign in to comment.