Skip to content

Commit ae4b0a8

Browse files
authored
Merge branch 'master' into add-doc-auto-cfg
2 parents 0e26e28 + 40eb356 commit ae4b0a8

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.18.1
2+
3+
- Add `with_p2p` on `Multiaddr`. See [PR 102].
4+
5+
[PR 102]: https://github.com/multiformats/rust-multiaddr/pull/102
6+
17
# 0.18.0
28

39
- Add `WebTransport` instance for `Multiaddr`. See [PR 70].

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ authors = ["dignifiedquire <[email protected]>", "Parity Technologies <ad
33
description = "Implementation of the multiaddr format"
44
edition = "2021"
55
rust-version = "1.59.0"
6-
homepage = "https://github.com/multiformats/rust-multiaddr"
6+
repository = "https://github.com/multiformats/rust-multiaddr"
77
keywords = ["multiaddr", "ipfs"]
88
license = "MIT"
99
name = "multiaddr"
1010
readme = "README.md"
11-
version = "0.18.0"
11+
version = "0.18.1"
1212

1313
[features]
1414
default = ["url"]

src/lib.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ use std::{
2727
sync::Arc,
2828
};
2929

30+
use libp2p_identity::PeerId;
31+
3032
#[cfg(feature = "url")]
3133
pub use self::from_url::{from_url, from_url_lossy, FromUrlErr};
3234

@@ -128,6 +130,18 @@ impl Multiaddr {
128130
self
129131
}
130132

133+
/// Appends the given [`PeerId`] if not yet present at the end of this multiaddress.
134+
///
135+
/// Fails if this address ends in a _different_ [`PeerId`].
136+
/// In that case, the original, unmodified address is returned.
137+
pub fn with_p2p(self, peer: PeerId) -> std::result::Result<Self, Self> {
138+
match self.iter().last() {
139+
Some(Protocol::P2p(p)) if p == peer => Ok(self),
140+
Some(Protocol::P2p(_)) => Err(self),
141+
_ => Ok(self.with(Protocol::P2p(peer))),
142+
}
143+
}
144+
131145
/// Returns the components of this multiaddress.
132146
///
133147
/// # Example
@@ -204,7 +218,7 @@ impl Multiaddr {
204218

205219
impl fmt::Debug for Multiaddr {
206220
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207-
self.to_string().fmt(f)
221+
fmt::Display::fmt(self, f)
208222
}
209223
}
210224

@@ -222,7 +236,7 @@ impl fmt::Display for Multiaddr {
222236
///
223237
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224238
for s in self.iter() {
225-
s.to_string().fmt(f)?;
239+
s.fmt(f)?;
226240
}
227241
Ok(())
228242
}

tests/lib.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,3 +661,66 @@ fn arbitrary_impl_for_all_proto_variants() {
661661
let variants = core::mem::variant_count::<Protocol>() as u8;
662662
assert_eq!(variants, Proto::IMPL_VARIANT_COUNT);
663663
}
664+
665+
mod multiaddr_with_p2p {
666+
use libp2p_identity::PeerId;
667+
use multiaddr::Multiaddr;
668+
669+
fn test_multiaddr_with_p2p(
670+
multiaddr: &str,
671+
peer: &str,
672+
expected: std::result::Result<&str, &str>,
673+
) {
674+
let peer = peer.parse::<PeerId>().unwrap();
675+
let expected = expected
676+
.map(|a| a.parse::<Multiaddr>().unwrap())
677+
.map_err(|a| a.parse::<Multiaddr>().unwrap());
678+
679+
let mut multiaddr = multiaddr.parse::<Multiaddr>().unwrap();
680+
// Testing multiple time to validate idempotence.
681+
for _ in 0..3 {
682+
let result = multiaddr.with_p2p(peer);
683+
assert_eq!(result, expected);
684+
multiaddr = result.unwrap_or_else(|addr| addr);
685+
}
686+
}
687+
688+
#[test]
689+
fn empty_multiaddr() {
690+
// Multiaddr is empty -> it should push and return Ok.
691+
test_multiaddr_with_p2p(
692+
"",
693+
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
694+
Ok("/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
695+
)
696+
}
697+
#[test]
698+
fn non_p2p_terminated() {
699+
// Last protocol is not p2p -> it should push and return Ok.
700+
test_multiaddr_with_p2p(
701+
"/ip4/127.0.0.1",
702+
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
703+
Ok("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
704+
)
705+
}
706+
707+
#[test]
708+
fn p2p_terminated_same_peer() {
709+
// Last protocol is p2p and the contained peer matches the provided one -> it should do nothing and return Ok.
710+
test_multiaddr_with_p2p(
711+
"/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
712+
"QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
713+
Ok("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
714+
)
715+
}
716+
717+
#[test]
718+
fn p2p_terminated_different_peer() {
719+
// Last protocol is p2p but the contained peer does not match the provided one -> it should do nothing and return Err.
720+
test_multiaddr_with_p2p(
721+
"/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
722+
"QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
723+
Err("/ip4/127.0.0.1/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"),
724+
)
725+
}
726+
}

0 commit comments

Comments
 (0)