levin: enable workspace lints (#292)

* levin: enable workspace lints

* use `drop()`

* dep fixes
This commit is contained in:
hinto-janai 2024-09-20 10:11:27 -04:00 committed by GitHub
parent 19150df355
commit 5588671501
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 66 additions and 45 deletions

1
Cargo.lock generated
View file

@ -724,6 +724,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bytes", "bytes",
"cfg-if",
"cuprate-helper", "cuprate-helper",
"futures", "futures",
"proptest", "proptest",

View file

@ -210,7 +210,6 @@ unseparated_literal_suffix = "deny"
unnecessary_safety_doc = "deny" unnecessary_safety_doc = "deny"
unnecessary_safety_comment = "deny" unnecessary_safety_comment = "deny"
unnecessary_self_imports = "deny" unnecessary_self_imports = "deny"
tests_outside_test_module = "deny"
string_to_string = "deny" string_to_string = "deny"
rest_pat_in_fully_bound_structs = "deny" rest_pat_in_fully_bound_structs = "deny"
redundant_type_annotations = "deny" redundant_type_annotations = "deny"

View file

@ -14,6 +14,7 @@ tracing = ["dep:tracing", "tokio-util/tracing"]
[dependencies] [dependencies]
cuprate-helper = { path = "../../helper", default-features = false, features = ["cast"] } cuprate-helper = { path = "../../helper", default-features = false, features = ["cast"] }
cfg-if = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
bytes = { workspace = true, features = ["std"] } bytes = { workspace = true, features = ["std"] }
bitflags = { workspace = true } bitflags = { workspace = true }
@ -26,4 +27,7 @@ proptest = { workspace = true }
rand = { workspace = true, features = ["std", "std_rng"] } rand = { workspace = true, features = ["std", "std_rng"] }
tokio-util = { workspace = true, features = ["io-util"]} tokio-util = { workspace = true, features = ["io-util"]}
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
futures = { workspace = true, features = ["std"] } futures = { workspace = true, features = ["std"] }
[lints]
workspace = true

View file

@ -47,7 +47,7 @@ pub struct LevinBucketCodec<C> {
impl<C> Default for LevinBucketCodec<C> { impl<C> Default for LevinBucketCodec<C> {
fn default() -> Self { fn default() -> Self {
LevinBucketCodec { Self {
state: LevinBucketState::WaitingForHeader, state: LevinBucketState::WaitingForHeader,
protocol: Protocol::default(), protocol: Protocol::default(),
handshake_message_seen: false, handshake_message_seen: false,
@ -56,8 +56,8 @@ impl<C> Default for LevinBucketCodec<C> {
} }
impl<C> LevinBucketCodec<C> { impl<C> LevinBucketCodec<C> {
pub fn new(protocol: Protocol) -> Self { pub const fn new(protocol: Protocol) -> Self {
LevinBucketCodec { Self {
state: LevinBucketState::WaitingForHeader, state: LevinBucketState::WaitingForHeader,
protocol, protocol,
handshake_message_seen: false, handshake_message_seen: false,
@ -112,8 +112,10 @@ impl<C: LevinCommand + Debug> Decoder for LevinBucketCodec<C> {
} }
} }
let _ = drop(std::mem::replace(
std::mem::replace(&mut self.state, LevinBucketState::WaitingForBody(head)); &mut self.state,
LevinBucketState::WaitingForBody(head),
));
} }
LevinBucketState::WaitingForBody(head) => { LevinBucketState::WaitingForBody(head) => {
let body_len = u64_to_usize(head.size); let body_len = u64_to_usize(head.size);
@ -145,7 +147,7 @@ impl<C: LevinCommand> Encoder<Bucket<C>> for LevinBucketCodec<C> {
type Error = BucketError; type Error = BucketError;
fn encode(&mut self, item: Bucket<C>, dst: &mut BytesMut) -> Result<(), Self::Error> { fn encode(&mut self, item: Bucket<C>, dst: &mut BytesMut) -> Result<(), Self::Error> {
if let Some(additional) = (HEADER_SIZE + item.body.len()).checked_sub(dst.capacity()) { 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); item.header.write_bytes_into(dst);

View file

@ -13,7 +13,7 @@
// copies or substantial portions of the Software. // 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. //! message.
use bitflags::bitflags; use bitflags::bitflags;
@ -62,7 +62,7 @@ bitflags! {
impl From<u32> for Flags { impl From<u32> for Flags {
fn from(value: u32) -> Self { fn from(value: u32) -> Self {
Flags(value) Self(value)
} }
} }
@ -99,9 +99,9 @@ impl<C: LevinCommand> BucketHead<C> {
/// ///
/// # Panics /// # Panics
/// This function will panic if there aren't enough bytes to fill the header. /// This function will panic if there aren't enough bytes to fill the header.
/// Currently [HEADER_SIZE] /// Currently [`HEADER_SIZE`]
pub fn from_bytes(buf: &mut BytesMut) -> BucketHead<C> { pub fn from_bytes(buf: &mut BytesMut) -> Self {
BucketHead { Self {
signature: buf.get_u64_le(), signature: buf.get_u64_le(),
size: buf.get_u64_le(), size: buf.get_u64_le(),
have_to_return_data: buf.get_u8() != 0, have_to_return_data: buf.get_u8() != 0,

View file

@ -33,6 +33,16 @@
#![deny(unused_mut)] #![deny(unused_mut)]
//#![deny(missing_docs)] //#![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 std::fmt::Debug;
use bytes::{Buf, Bytes}; use bytes::{Buf, Bytes};
@ -99,7 +109,7 @@ pub struct Protocol {
impl Default for Protocol { impl Default for Protocol {
fn default() -> Self { fn default() -> Self {
Protocol { Self {
version: MONERO_PROTOCOL_VERSION, version: MONERO_PROTOCOL_VERSION,
signature: MONERO_LEVIN_SIGNATURE, signature: MONERO_LEVIN_SIGNATURE,
max_packet_size_before_handshake: MONERO_MAX_PACKET_SIZE_BEFORE_HANDSHAKE, max_packet_size_before_handshake: MONERO_MAX_PACKET_SIZE_BEFORE_HANDSHAKE,
@ -130,22 +140,22 @@ pub enum MessageType {
impl MessageType { impl MessageType {
/// Returns if the message requires a response /// 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 { match self {
MessageType::Request => true, Self::Request => true,
MessageType::Response | MessageType::Notification => false, Self::Response | Self::Notification => false,
} }
} }
/// Returns the `MessageType` given the flags and have_to_return_data fields /// Returns the `MessageType` given the flags and `have_to_return_data` fields
pub fn from_flags_and_have_to_return( pub const fn from_flags_and_have_to_return(
flags: Flags, flags: Flags,
have_to_return: bool, have_to_return: bool,
) -> Result<Self, BucketError> { ) -> Result<Self, BucketError> {
Ok(match (flags, have_to_return) { Ok(match (flags, have_to_return) {
(Flags::REQUEST, true) => MessageType::Request, (Flags::REQUEST, true) => Self::Request,
(Flags::REQUEST, false) => MessageType::Notification, (Flags::REQUEST, false) => Self::Notification,
(Flags::RESPONSE, false) => MessageType::Response, (Flags::RESPONSE, false) => Self::Response,
_ => { _ => {
return Err(BucketError::InvalidHeaderFlags( return Err(BucketError::InvalidHeaderFlags(
"Unable to assign a message type to this bucket", "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 { match self {
MessageType::Request | MessageType::Notification => header::Flags::REQUEST, Self::Request | Self::Notification => Flags::REQUEST,
MessageType::Response => header::Flags::RESPONSE, Self::Response => Flags::RESPONSE,
} }
} }
} }
@ -173,7 +183,7 @@ pub struct BucketBuilder<C> {
} }
impl<C: LevinCommand> BucketBuilder<C> { impl<C: LevinCommand> BucketBuilder<C> {
pub fn new(protocol: &Protocol) -> Self { pub const fn new(protocol: &Protocol) -> Self {
Self { Self {
signature: Some(protocol.signature), signature: Some(protocol.signature),
ty: None, ty: None,
@ -185,27 +195,27 @@ impl<C: LevinCommand> BucketBuilder<C> {
} }
pub fn set_signature(&mut self, sig: u64) { 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) { 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) { 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) { 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) { 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) { pub fn set_body(&mut self, body: Bytes) {
self.body = Some(body) self.body = Some(body);
} }
pub fn finish(self) -> Bucket<C> { pub fn finish(self) -> Bucket<C> {

View file

@ -33,13 +33,13 @@ pub enum LevinMessage<T: LevinBody> {
impl<T: LevinBody> From<T> for LevinMessage<T> { impl<T: LevinBody> From<T> for LevinMessage<T> {
fn from(value: T) -> Self { fn from(value: T) -> Self {
LevinMessage::Body(value) Self::Body(value)
} }
} }
impl<T: LevinBody> From<Bucket<T::Command>> for LevinMessage<T> { impl<T: LevinBody> From<Bucket<T::Command>> for LevinMessage<T> {
fn from(value: Bucket<T::Command>) -> Self { fn from(value: Bucket<T::Command>) -> Self {
LevinMessage::Bucket(value) Self::Bucket(value)
} }
} }
@ -58,7 +58,7 @@ pub struct Dummy(pub usize);
impl<T: LevinBody> From<Dummy> for LevinMessage<T> { impl<T: LevinBody> From<Dummy> for LevinMessage<T> {
fn from(value: Dummy) -> Self { fn from(value: Dummy) -> Self {
LevinMessage::Dummy(value.0) Self::Dummy(value.0)
} }
} }
@ -76,12 +76,11 @@ pub fn make_fragmented_messages<T: LevinBody>(
fragment_size: usize, fragment_size: usize,
message: T, message: T,
) -> Result<Vec<Bucket<T::Command>>, BucketError> { ) -> Result<Vec<Bucket<T::Command>>, BucketError> {
if fragment_size * 2 < HEADER_SIZE { assert!(
panic!( fragment_size * 2 >= HEADER_SIZE,
"Fragment size: {fragment_size}, is too small, must be at least {}", "Fragment size: {fragment_size}, is too small, must be at least {}",
2 * HEADER_SIZE 2 * HEADER_SIZE
); );
}
let mut builder = BucketBuilder::new(protocol); let mut builder = BucketBuilder::new(protocol);
message.encode(&mut builder)?; message.encode(&mut builder)?;

View file

@ -1,3 +1,9 @@
#![expect(
clippy::tests_outside_test_module,
unused_crate_dependencies,
reason = "outer test module"
)]
use bytes::{Buf, BufMut, Bytes, BytesMut}; use bytes::{Buf, BufMut, Bytes, BytesMut};
use futures::{SinkExt, StreamExt}; use futures::{SinkExt, StreamExt};
use proptest::{prelude::any_with, prop_assert_eq, proptest, sample::size_range}; use proptest::{prelude::any_with, prop_assert_eq, proptest, sample::size_range};
@ -58,12 +64,12 @@ impl LevinBody for TestBody {
) -> Result<Self, BucketError> { ) -> Result<Self, BucketError> {
let size = u64_to_usize(body.get_u64_le()); let size = u64_to_usize(body.get_u64_le());
// bucket // 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<Self::Command>) -> Result<(), BucketError> { fn encode(self, builder: &mut BucketBuilder<Self::Command>) -> Result<(), BucketError> {
match self { match self {
TestBody::Bytes(len, bytes) => { Self::Bytes(len, bytes) => {
let mut buf = BytesMut::new(); let mut buf = BytesMut::new();
buf.put_u64_le(len as u64); buf.put_u64_le(len as u64);
buf.extend_from_slice(bytes.as_ref()); buf.extend_from_slice(bytes.as_ref());
@ -141,12 +147,12 @@ proptest! {
message2.extend_from_slice(&fragments[0].body[(33 + 8)..]); message2.extend_from_slice(&fragments[0].body[(33 + 8)..]);
for frag in fragments.iter().skip(1) { 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()); 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); prop_assert_eq!(*byte, 0);
} }
} }