mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-16 15:58:17 +00:00
levin: enable workspace lints (#292)
* levin: enable workspace lints * use `drop()` * dep fixes
This commit is contained in:
parent
19150df355
commit
5588671501
8 changed files with 66 additions and 45 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue