Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
toolchain: [stable]
runs-on: ${{ matrix.platform }}

steps:
Expand All @@ -22,14 +21,20 @@ jobs:
path: ~/.cargo
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Install Rust Toolchain
- name: Install Rust Stable Toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.toolchain }}
toolchain: stable
override: true
components: rustfmt, clippy

- name: Install Rust Nightly Toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly

- name: Check Code Format
uses: actions-rs/cargo@v1
with:
Expand All @@ -54,6 +59,14 @@ jobs:
command: test
args: --all-features --workspace

- name: Nightly Test
uses: actions-rs/cargo@v1
env:
RUSTFLAGS: '--cfg nightly -Zcrate-attr=feature(variant_count)'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot that we need to activate features, this is 🔥🔥🔥

with:
toolchain: nightly
command: test

coverage:
name: Code Coverage
runs-on: ubuntu-latest
Expand Down
8 changes: 4 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ impl fmt::Display for Error {
Error::DataLessThanLen => f.write_str("we have less data than indicated by length"),
Error::InvalidMultiaddr => f.write_str("invalid multiaddr"),
Error::InvalidProtocolString => f.write_str("invalid protocol string"),
Error::InvalidUvar(e) => write!(f, "failed to decode unsigned varint: {}", e),
Error::ParsingError(e) => write!(f, "failed to parse: {}", e),
Error::UnknownProtocolId(id) => write!(f, "unknown protocol id: {}", id),
Error::InvalidUvar(e) => write!(f, "failed to decode unsigned varint: {e}"),
Error::ParsingError(e) => write!(f, "failed to parse: {e}"),
Error::UnknownProtocolId(id) => write!(f, "unknown protocol id: {id}"),
Error::UnknownProtocolString(string) => {
write!(f, "unknown protocol string: {}", string)
write!(f, "unknown protocol string: {string}")
}
}
}
Expand Down
28 changes: 14 additions & 14 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,19 +569,19 @@ impl<'a> fmt::Display for Protocol<'a> {
use self::Protocol::*;
write!(f, "/{}", self.tag())?;
match self {
Dccp(port) => write!(f, "/{}", port),
Dns(s) => write!(f, "/{}", s),
Dns4(s) => write!(f, "/{}", s),
Dns6(s) => write!(f, "/{}", s),
Dnsaddr(s) => write!(f, "/{}", s),
Ip4(addr) => write!(f, "/{}", addr),
Ip6(addr) => write!(f, "/{}", addr),
Dccp(port) => write!(f, "/{port}"),
Dns(s) => write!(f, "/{s}"),
Dns4(s) => write!(f, "/{s}"),
Dns6(s) => write!(f, "/{s}"),
Dnsaddr(s) => write!(f, "/{s}"),
Ip4(addr) => write!(f, "/{addr}"),
Ip6(addr) => write!(f, "/{addr}"),
Certhash(hash) => write!(
f,
"/{}",
multibase::encode(multibase::Base::Base64Url, hash.to_bytes())
),
Memory(port) => write!(f, "/{}", port),
Memory(port) => write!(f, "/{port}"),
Onion(addr, port) => {
let s = BASE32.encode(addr.as_ref());
write!(f, "/{}:{}", s.to_lowercase(), port)
Expand All @@ -591,19 +591,19 @@ impl<'a> fmt::Display for Protocol<'a> {
write!(f, "/{}:{}", s.to_lowercase(), addr.port())
}
P2p(c) => write!(f, "/{}", multibase::Base::Base58Btc.encode(c.to_bytes())),
Sctp(port) => write!(f, "/{}", port),
Tcp(port) => write!(f, "/{}", port),
Udp(port) => write!(f, "/{}", port),
Unix(s) => write!(f, "/{}", s),
Sctp(port) => write!(f, "/{port}"),
Tcp(port) => write!(f, "/{port}"),
Udp(port) => write!(f, "/{port}"),
Unix(s) => write!(f, "/{s}"),
Ws(s) if s != "/" => {
let encoded =
percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
write!(f, "/{}", encoded)
write!(f, "/{encoded}")
}
Wss(s) if s != "/" => {
let encoded =
percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
write!(f, "/{}", encoded)
write!(f, "/{encoded}")
}
_ => Ok(()),
}
Expand Down
15 changes: 14 additions & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,14 @@ impl Arbitrary for Ma {
#[derive(PartialEq, Eq, Clone, Debug)]
struct Proto(Protocol<'static>);

impl Proto {
const IMPL_VARIANT_COUNT: u8 = 32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking of directly on the enum as Protocol::VARIANT_COUNT.

I am sure there are also proc-macros for this that we could enable only during testing if this nightly stuff is too fancy 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but Protocol lives in the crate, the VARIANT_COUNT refers to Proto's arbitrary implementation count. Protocol's count is what we get with mem::variant_count you mean implementing it on Protocol in the tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that would unnecessarily increase the public API. Leave it as is! :)

}

impl Arbitrary for Proto {
fn arbitrary(g: &mut Gen) -> Self {
use Protocol::*;
match u8::arbitrary(g) % 32 {
match u8::arbitrary(g) % Proto::IMPL_VARIANT_COUNT {
0 => Proto(Dccp(Arbitrary::arbitrary(g))),
1 => Proto(Dns(Cow::Owned(SubString::arbitrary(g).0))),
2 => Proto(Dns4(Cow::Owned(SubString::arbitrary(g).0))),
Expand Down Expand Up @@ -639,3 +643,12 @@ fn protocol_stack() {
assert_eq!(ps, toks);
}
}

// Assert all `Protocol` variants are covered
// in its `Arbitrary` impl.
#[cfg(nightly)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done! At first I thought that we'd need the rust-version proc macro here but cfgs also work very well!

#[test]
fn arbitrary_impl_for_all_proto_variants() {
let variants = core::mem::variant_count::<Protocol>() as u8;
assert_eq!(variants, Proto::IMPL_VARIANT_COUNT);
}