diff --git a/Cargo.lock b/Cargo.lock index 61fa2a2a..054ca85e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -724,6 +724,7 @@ version = "0.1.0" dependencies = [ "bitflags 2.6.0", "bytes", + "cfg-if", "cuprate-helper", "futures", "proptest", diff --git a/Cargo.toml b/Cargo.toml index f991f73d..2554fbde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -210,7 +210,6 @@ unseparated_literal_suffix = "deny" unnecessary_safety_doc = "deny" unnecessary_safety_comment = "deny" unnecessary_self_imports = "deny" -tests_outside_test_module = "deny" string_to_string = "deny" rest_pat_in_fully_bound_structs = "deny" redundant_type_annotations = "deny" diff --git a/net/levin/Cargo.toml b/net/levin/Cargo.toml index 1c585b9c..68c32e54 100644 --- a/net/levin/Cargo.toml +++ b/net/levin/Cargo.toml @@ -14,6 +14,7 @@ tracing = ["dep:tracing", "tokio-util/tracing"] [dependencies] cuprate-helper = { path = "../../helper", default-features = false, features = ["cast"] } +cfg-if = { workspace = true } thiserror = { workspace = true } bytes = { workspace = true, features = ["std"] } bitflags = { workspace = true } @@ -26,4 +27,7 @@ proptest = { workspace = true } rand = { workspace = true, features = ["std", "std_rng"] } tokio-util = { workspace = true, features = ["io-util"]} tokio = { workspace = true, features = ["full"] } -futures = { workspace = true, features = ["std"] } \ No newline at end of file +futures = { workspace = true, features = ["std"] } + +[lints] +workspace = true \ No newline at end of file diff --git a/net/levin/src/codec.rs b/net/levin/src/codec.rs index 1177733f..4c7695ef 100644 --- a/net/levin/src/codec.rs +++ b/net/levin/src/codec.rs @@ -47,7 +47,7 @@ pub struct LevinBucketCodec { impl Default for LevinBucketCodec { fn default() -> Self { - LevinBucketCodec { + Self { state: LevinBucketState::WaitingForHeader, protocol: Protocol::default(), handshake_message_seen: false, @@ -56,8 +56,8 @@ impl Default for LevinBucketCodec { } impl LevinBucketCodec { - pub fn new(protocol: Protocol) -> Self { - LevinBucketCodec { + pub const fn new(protocol: Protocol) -> Self { + Self { state: LevinBucketState::WaitingForHeader, protocol, handshake_message_seen: false, @@ -112,8 +112,10 @@ impl Decoder for LevinBucketCodec { } } - let _ = - std::mem::replace(&mut self.state, LevinBucketState::WaitingForBody(head)); + drop(std::mem::replace( + &mut self.state, + LevinBucketState::WaitingForBody(head), + )); } LevinBucketState::WaitingForBody(head) => { let body_len = u64_to_usize(head.size); @@ -145,7 +147,7 @@ impl Encoder> for LevinBucketCodec { type Error = BucketError; fn encode(&mut self, item: Bucket, dst: &mut BytesMut) -> Result<(), Self::Error> { if let Some(additional) = (HEADER_SIZE + item.body.len()).checked_sub(dst.capacity()) { - dst.reserve(additional) + dst.reserve(additional); } item.header.write_bytes_into(dst); diff --git a/net/levin/src/header.rs b/net/levin/src/header.rs index 7acd0858..057eee8c 100644 --- a/net/levin/src/header.rs +++ b/net/levin/src/header.rs @@ -13,7 +13,7 @@ // copies or substantial portions of the Software. // -//! This module provides a struct BucketHead for the header of a levin protocol +//! This module provides a struct `BucketHead` for the header of a levin protocol //! message. use bitflags::bitflags; @@ -62,7 +62,7 @@ bitflags! { impl From for Flags { fn from(value: u32) -> Self { - Flags(value) + Self(value) } } @@ -99,9 +99,9 @@ impl BucketHead { /// /// # Panics /// This function will panic if there aren't enough bytes to fill the header. - /// Currently [HEADER_SIZE] - pub fn from_bytes(buf: &mut BytesMut) -> BucketHead { - BucketHead { + /// Currently [`HEADER_SIZE`] + pub fn from_bytes(buf: &mut BytesMut) -> Self { + Self { signature: buf.get_u64_le(), size: buf.get_u64_le(), have_to_return_data: buf.get_u8() != 0, diff --git a/net/levin/src/lib.rs b/net/levin/src/lib.rs index ab03bfb4..a3f4b694 100644 --- a/net/levin/src/lib.rs +++ b/net/levin/src/lib.rs @@ -33,6 +33,16 @@ #![deny(unused_mut)] //#![deny(missing_docs)] +cfg_if::cfg_if! { + // Used in `tests/`. + if #[cfg(test)] { + use futures as _; + use proptest as _; + use rand as _; + use tokio as _; + } +} + use std::fmt::Debug; use bytes::{Buf, Bytes}; @@ -99,7 +109,7 @@ pub struct Protocol { impl Default for Protocol { fn default() -> Self { - Protocol { + Self { version: MONERO_PROTOCOL_VERSION, signature: MONERO_LEVIN_SIGNATURE, max_packet_size_before_handshake: MONERO_MAX_PACKET_SIZE_BEFORE_HANDSHAKE, @@ -130,22 +140,22 @@ pub enum MessageType { impl MessageType { /// Returns if the message requires a response - pub fn have_to_return_data(&self) -> bool { + pub const fn have_to_return_data(&self) -> bool { match self { - MessageType::Request => true, - MessageType::Response | MessageType::Notification => false, + Self::Request => true, + Self::Response | Self::Notification => false, } } - /// Returns the `MessageType` given the flags and have_to_return_data fields - pub fn from_flags_and_have_to_return( + /// Returns the `MessageType` given the flags and `have_to_return_data` fields + pub const fn from_flags_and_have_to_return( flags: Flags, have_to_return: bool, ) -> Result { Ok(match (flags, have_to_return) { - (Flags::REQUEST, true) => MessageType::Request, - (Flags::REQUEST, false) => MessageType::Notification, - (Flags::RESPONSE, false) => MessageType::Response, + (Flags::REQUEST, true) => Self::Request, + (Flags::REQUEST, false) => Self::Notification, + (Flags::RESPONSE, false) => Self::Response, _ => { return Err(BucketError::InvalidHeaderFlags( "Unable to assign a message type to this bucket", @@ -154,10 +164,10 @@ impl MessageType { }) } - pub fn as_flags(&self) -> header::Flags { + pub const fn as_flags(&self) -> Flags { match self { - MessageType::Request | MessageType::Notification => header::Flags::REQUEST, - MessageType::Response => header::Flags::RESPONSE, + Self::Request | Self::Notification => Flags::REQUEST, + Self::Response => Flags::RESPONSE, } } } @@ -173,7 +183,7 @@ pub struct BucketBuilder { } impl BucketBuilder { - pub fn new(protocol: &Protocol) -> Self { + pub const fn new(protocol: &Protocol) -> Self { Self { signature: Some(protocol.signature), ty: None, @@ -185,27 +195,27 @@ impl BucketBuilder { } pub fn set_signature(&mut self, sig: u64) { - self.signature = Some(sig) + self.signature = Some(sig); } pub fn set_message_type(&mut self, ty: MessageType) { - self.ty = Some(ty) + self.ty = Some(ty); } pub fn set_command(&mut self, command: C) { - self.command = Some(command) + self.command = Some(command); } pub fn set_return_code(&mut self, code: i32) { - self.return_code = Some(code) + self.return_code = Some(code); } pub fn set_protocol_version(&mut self, version: u32) { - self.protocol_version = Some(version) + self.protocol_version = Some(version); } pub fn set_body(&mut self, body: Bytes) { - self.body = Some(body) + self.body = Some(body); } pub fn finish(self) -> Bucket { diff --git a/net/levin/src/message.rs b/net/levin/src/message.rs index 19aa1b50..32be6536 100644 --- a/net/levin/src/message.rs +++ b/net/levin/src/message.rs @@ -33,13 +33,13 @@ pub enum LevinMessage { impl From for LevinMessage { fn from(value: T) -> Self { - LevinMessage::Body(value) + Self::Body(value) } } impl From> for LevinMessage { fn from(value: Bucket) -> Self { - LevinMessage::Bucket(value) + Self::Bucket(value) } } @@ -58,7 +58,7 @@ pub struct Dummy(pub usize); impl From for LevinMessage { fn from(value: Dummy) -> Self { - LevinMessage::Dummy(value.0) + Self::Dummy(value.0) } } @@ -76,12 +76,11 @@ pub fn make_fragmented_messages( fragment_size: usize, message: T, ) -> Result>, BucketError> { - if fragment_size * 2 < HEADER_SIZE { - panic!( - "Fragment size: {fragment_size}, is too small, must be at least {}", - 2 * HEADER_SIZE - ); - } + assert!( + fragment_size * 2 >= HEADER_SIZE, + "Fragment size: {fragment_size}, is too small, must be at least {}", + 2 * HEADER_SIZE + ); let mut builder = BucketBuilder::new(protocol); message.encode(&mut builder)?; diff --git a/net/levin/tests/fragmented_message.rs b/net/levin/tests/fragmented_message.rs index 512fd461..f34b1458 100644 --- a/net/levin/tests/fragmented_message.rs +++ b/net/levin/tests/fragmented_message.rs @@ -1,3 +1,9 @@ +#![expect( + clippy::tests_outside_test_module, + unused_crate_dependencies, + reason = "outer test module" +)] + use bytes::{Buf, BufMut, Bytes, BytesMut}; use futures::{SinkExt, StreamExt}; use proptest::{prelude::any_with, prop_assert_eq, proptest, sample::size_range}; @@ -58,12 +64,12 @@ impl LevinBody for TestBody { ) -> Result { let size = u64_to_usize(body.get_u64_le()); // bucket - Ok(TestBody::Bytes(size, body.copy_to_bytes(size))) + Ok(Self::Bytes(size, body.copy_to_bytes(size))) } fn encode(self, builder: &mut BucketBuilder) -> Result<(), BucketError> { match self { - TestBody::Bytes(len, bytes) => { + Self::Bytes(len, bytes) => { let mut buf = BytesMut::new(); buf.put_u64_le(len as u64); buf.extend_from_slice(bytes.as_ref()); @@ -141,12 +147,12 @@ proptest! { message2.extend_from_slice(&fragments[0].body[(33 + 8)..]); for frag in fragments.iter().skip(1) { - message2.extend_from_slice(frag.body.as_ref()) + message2.extend_from_slice(frag.body.as_ref()); } prop_assert_eq!(message.as_slice(), &message2[0..message.len()], "numb_fragments: {}", fragments.len()); - for byte in message2[message.len()..].iter(){ + for byte in &message2[message.len()..]{ prop_assert_eq!(*byte, 0); } }