diff --git a/Cargo.toml b/Cargo.toml index 8928a92..53af241 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,10 @@ opt-level = 3 [patch.crates-io] fastwebsockets = { git = "https://github.com/r58Playz/fastwebsockets" } h2 = { git = "https://github.com/r58Playz/h2-wasm" } + +[workspace.lints.clippy] +pedantic = { level = "warn", priority = -1 } +must_use_candidate = "allow" +missing_errors_doc = "allow" +module_name_repetitions = "allow" +struct_excessive_bools = "allow" diff --git a/client/Cargo.toml b/client/Cargo.toml index 07a61b5..654969e 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -3,6 +3,9 @@ name = "epoxy-client" version = "2.1.15" edition = "2021" +[lints] +workspace = true + [lib] crate-type = ["cdylib"] diff --git a/client/src/lib.rs b/client/src/lib.rs index 949839e..39b494f 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,4 +1,5 @@ #![feature(let_chains, impl_trait_in_assoc_type)] + use std::{error::Error, pin::Pin, str::FromStr, sync::Arc}; #[cfg(feature = "full")] @@ -89,7 +90,7 @@ impl TryFrom for Uri { } else if let Some(value) = value.as_string() { value.try_into().map_err(EpoxyError::from) } else { - Err(EpoxyError::InvalidUrl(format!("{:?}", value))) + Err(EpoxyError::InvalidUrl(format!("{value:?}"))) } } } @@ -176,11 +177,12 @@ pub enum EpoxyError { } impl EpoxyError { + #[expect(clippy::needless_pass_by_value)] pub fn wisp_transport(value: JsValue) -> Self { if let Some(err) = value.dyn_ref::() { Self::WispTransport(err.to_string().into()) } else { - Self::WispTransport(format!("{:?}", value)) + Self::WispTransport(format!("{value:?}")) } } } @@ -349,7 +351,7 @@ fn create_wisp_transport(function: Function) -> ProviderWispTransportGenerator { .map(|x| { let pkt = x.map_err(EpoxyError::wisp_transport)?; let arr: ArrayBuffer = pkt.dyn_into().map_err(|x| { - EpoxyError::InvalidWispTransportPacket(format!("{:?}", x)) + EpoxyError::InvalidWispTransportPacket(format!("{x:?}")) })?; Ok::(BytesMut::from( Uint8Array::new(&arr).to_vec().as_slice(), @@ -395,10 +397,10 @@ impl EpoxyClient { options: EpoxyClientOptions, ) -> Result { let stream_provider = if let Some(wisp_url) = transport.as_string() { - let wisp_uri: Uri = wisp_url.clone().try_into()?; - if wisp_uri.scheme_str() != Some("wss") && wisp_uri.scheme_str() != Some("ws") { + let uri: Uri = wisp_url.clone().try_into()?; + if uri.scheme_str() != Some("wss") && uri.scheme_str() != Some("ws") { return Err(EpoxyError::InvalidUrlScheme( - wisp_uri.scheme_str().map(ToString::to_string), + uri.scheme_str().map(ToString::to_string), )); } @@ -538,18 +540,18 @@ impl EpoxyClient { None }; - let res = self.client.request(req).await; - match res { - Ok(res) => { - if is_redirect(res.status().as_u16()) + let resp = self.client.request(req).await; + match resp { + Ok(resp) => { + if is_redirect(resp.status().as_u16()) && let Some(mut new_req) = new_req - && let Some(location) = res.headers().get(LOCATION) + && let Some(location) = resp.headers().get(LOCATION) && let Ok(redirect_url) = new_req.uri().get_redirect(location) { *new_req.uri_mut() = redirect_url; - Ok(EpoxyResponse::Redirect((res, new_req))) + Ok(EpoxyResponse::Redirect((resp, new_req))) } else { - Ok(EpoxyResponse::Success(res)) + Ok(EpoxyResponse::Success(resp)) } } Err(err) => Err(err.into()), @@ -570,14 +572,15 @@ impl EpoxyClient { EpoxyResponse::Redirect((_, req)) => { redirected = true; current_url = req.uri().clone(); - current_resp = self.send_req_inner(req, should_redirect).await? + current_resp = self.send_req_inner(req, should_redirect).await?; } } } match current_resp { - EpoxyResponse::Success(resp) => Ok((resp, current_url, redirected)), - EpoxyResponse::Redirect((resp, _)) => Ok((resp, current_url, redirected)), + EpoxyResponse::Redirect((resp, _)) | EpoxyResponse::Success(resp) => { + Ok((resp, current_url, redirected)) + } } } @@ -753,7 +756,7 @@ impl EpoxyClient { utils::define_property(&resp, "redirected", redirected.into()); let raw_headers = Object::new(); - for (k, v) in response_headers_raw.iter() { + for (k, v) in &response_headers_raw { let k = k.as_str(); let v: JsValue = v.to_str()?.to_string().into(); let jv = object_get(&raw_headers, k); diff --git a/client/src/stream_provider.rs b/client/src/stream_provider.rs index c5046d1..1d637e8 100644 --- a/client/src/stream_provider.rs +++ b/client/src/stream_provider.rs @@ -81,9 +81,7 @@ impl StreamProvider { let mut client_config = if options.disable_certificate_validation { client_config .dangerous() - .with_custom_certificate_verifier(Arc::new(NoCertificateVerification( - provider, - ))) + .with_custom_certificate_verifier(Arc::new(NoCertificateVerification(provider))) } else { cfg_if! { if #[cfg(feature = "full")] { @@ -97,9 +95,9 @@ impl StreamProvider { }) .collect(); let pems = pems.map_err(EpoxyError::Pemfile)??; - let certstore = RootCertStore::from_iter(pems.into_iter().chain(TLS_SERVER_ROOTS.iter().cloned())); + let certstore: RootCertStore = pems.into_iter().chain(TLS_SERVER_ROOTS.iter().cloned()).collect(); } else { - let certstore = RootCertStore::from_iter(TLS_SERVER_ROOTS.iter().cloned()); + let certstore: RootCertStore = TLS_SERVER_ROOTS.iter().cloned().collect(); } } client_config.with_root_certificates(certstore) @@ -149,7 +147,7 @@ impl StreamProvider { let current_client = self.current_client.clone(); spawn_local(async move { match fut.await { - Ok(_) => console_log!("epoxy: wisp multiplexor task ended successfully"), + Ok(()) => console_log!("epoxy: wisp multiplexor task ended successfully"), Err(x) => console_error!( "epoxy: wisp multiplexor task ended with an error: {} {:?}", x, @@ -220,8 +218,7 @@ impl StreamProvider { .get_ref() .1 .alpn_protocol() - .map(|x| x == "h2".as_bytes()) - .unwrap_or(false); + .is_some_and(|x| x == "h2".as_bytes()); Ok(IgnoreCloseNotify { inner: stream.into(), h2_negotiated, @@ -253,7 +250,9 @@ impl hyper::rt::Read for HyperIo { cx: &mut std::task::Context<'_>, mut buf: hyper::rt::ReadBufCursor<'_>, ) -> Poll> { - let buf_slice: &mut [u8] = unsafe { std::mem::transmute(buf.as_mut()) }; + let buf_slice: &mut [u8] = unsafe { + &mut *(std::ptr::from_mut::<[std::mem::MaybeUninit]>(buf.as_mut()) as *mut [u8]) + }; match self.project().inner.poll_read(cx, buf_slice) { Poll::Ready(bytes_read) => { let bytes_read = bytes_read?; @@ -327,11 +326,14 @@ impl ConnectSvc for StreamProviderService { Box::pin(async move { let scheme = req.scheme_str().ok_or(EpoxyError::InvalidUrlScheme(None))?; let host = req.host().ok_or(EpoxyError::NoUrlHost)?.to_string(); - let port = req.port_u16().map(Ok).unwrap_or_else(|| match scheme { - "https" | "wss" => Ok(443), - "http" | "ws" => Ok(80), - _ => Err(EpoxyError::NoUrlPort), - })?; + let port = req.port_u16().map_or_else( + || match scheme { + "https" | "wss" => Ok(443), + "http" | "ws" => Ok(80), + _ => Err(EpoxyError::NoUrlPort), + }, + Ok, + )?; Ok(HyperIo { inner: match scheme { "https" => Either::Left(provider.get_tls_stream(host, port, true).await?), diff --git a/client/src/tokioio.rs b/client/src/tokioio.rs index a5797ee..68ff49d 100644 --- a/client/src/tokioio.rs +++ b/client/src/tokioio.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -//! hyper_util::rt::tokio::TokioIo +//! `hyper_util::rt::tokio::TokioIo` use std::{ pin::Pin, diff --git a/client/src/utils/js.rs b/client/src/utils/js.rs index ec43c3a..7de8ebe 100644 --- a/client/src/utils/js.rs +++ b/client/src/utils/js.rs @@ -92,7 +92,7 @@ extern "C" { pub async fn convert_body(val: JsValue) -> Result<(Uint8Array, Option), JsValue> { let req: Array = convert_body_inner(val).await?.unchecked_into(); - let content_type: Option = object_truthy(req.at(1)).map(|x| x.unchecked_into()); + let content_type: Option = object_truthy(req.at(1)).map(wasm_bindgen::JsCast::unchecked_into); Ok((req.at(0).unchecked_into(), content_type.map(Into::into))) } @@ -109,13 +109,13 @@ impl StreamingInnerBody { pub fn from_teed(a: ReadableStream, b: ReadableStream) -> Result { let reader = a .try_into_stream() - .map_err(|x| EpoxyError::StreamingBodyConvertFailed(format!("{:?}", x)))?; + .map_err(|x| EpoxyError::StreamingBodyConvertFailed(format!("{x:?}")))?; let reader = reader .then(|x| async { Ok::(Bytes::from(convert_body(x?).await?.0.to_vec())) }) .map_ok(http_body::Frame::data); - let reader = reader.map_err(|x| std::io::Error::other(format!("{:?}", x))); + let reader = reader.map_err(|x| std::io::Error::other(format!("{x:?}"))); let reader = Box::pin(SendWrapper::new(reader)); Ok(Self(reader, SendWrapper::new(b))) @@ -134,7 +134,7 @@ impl Clone for StreamingInnerBody { fn clone(&self) -> Self { match ReadableStream::from_raw(self.1.as_raw().clone()) .try_tee() - .map_err(|x| EpoxyError::StreamingBodyTeeFailed(format!("{:?}", x))) + .map_err(|x| EpoxyError::StreamingBodyTeeFailed(format!("{x:?}"))) .and_then(|(a, b)| StreamingInnerBody::from_teed(a, b)) { Ok(x) => x, @@ -157,7 +157,7 @@ impl MaybeStreamingBody { Self::Streaming(x) => { let (a, b) = ReadableStream::from_raw(x) .try_tee() - .map_err(|x| EpoxyError::StreamingBodyTeeFailed(format!("{:?}", x)))?; + .map_err(|x| EpoxyError::StreamingBodyTeeFailed(format!("{x:?}")))?; Ok(Either::Left(StreamBody::new( StreamingInnerBody::from_teed(a, b)?, @@ -172,7 +172,7 @@ pub async fn convert_streaming_body( val: JsValue, ) -> Result<(MaybeStreamingBody, Option), JsValue> { let req: Array = convert_streaming_body_inner(val).await?.unchecked_into(); - let content_type: Option = object_truthy(req.at(2)).map(|x| x.unchecked_into()); + let content_type: Option = object_truthy(req.at(2)).map(wasm_bindgen::JsCast::unchecked_into); let body = if req.at(0).is_truthy() { MaybeStreamingBody::Streaming(req.at(1).unchecked_into()) diff --git a/client/src/utils/mod.rs b/client/src/utils/mod.rs index dc39ef0..1c6fde6 100644 --- a/client/src/utils/mod.rs +++ b/client/src/utils/mod.rs @@ -131,7 +131,8 @@ pub fn poll_read_buf( let n = { let dst = buf.chunk_mut(); - let dst = unsafe { std::mem::transmute::<&mut UninitSlice, &mut [u8]>(dst) }; + let dst = + unsafe { &mut *(std::ptr::from_mut::(dst) as *mut [u8]) }; ready!(io.poll_read(cx, dst)?) }; @@ -147,9 +148,8 @@ impl Stream for ReaderStream { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.as_mut().project(); - let reader = match this.reader.as_pin_mut() { - Some(r) => r, - None => return Poll::Ready(None), + let Some(reader) = this.reader.as_pin_mut() else { + return Poll::Ready(None); }; if this.buf.capacity() == 0 { diff --git a/client/src/utils/rustls.rs b/client/src/utils/rustls.rs index a5e3101..22bf2bf 100644 --- a/client/src/utils/rustls.rs +++ b/client/src/utils/rustls.rs @@ -26,7 +26,7 @@ fn map_close_notify(x: std::io::Result) -> std::io::Result { Err(x) => { // hacky way to find if it's actually a rustls close notify error if x.kind() == ErrorKind::UnexpectedEof - && format!("{:?}", x).contains("TLS close_notify") + && format!("{x:?}").contains("TLS close_notify") { Ok(0) } else { diff --git a/client/src/ws_wrapper.rs b/client/src/ws_wrapper.rs index c86141c..11a6dc7 100644 --- a/client/src/ws_wrapper.rs +++ b/client/src/ws_wrapper.rs @@ -76,7 +76,7 @@ impl WebSocketRead for WebSocketReader { } let res = futures_util::select! { data = self.read_rx.recv_async() => data.ok(), - _ = self.close_event.listen().fuse() => Some(M::Closed), + () = self.close_event.listen().fuse() => Some(M::Closed), }; match res.ok_or(WispError::WsImplSocketClosed)? { M::Message(bin) => Ok(Frame::binary(Payload::Bytes(BytesMut::from( @@ -123,8 +123,7 @@ impl WebSocketWrapper { let onerror_event = error_event.clone(); let onerror = Closure::wrap(Box::new(move |e| { let _ = onerror_tx.send(WebSocketMessage::Error(WebSocketError::Unknown(format!( - "{:?}", - e + "{e:?}" )))); onerror_closed.store(true, Ordering::Release); onerror_close.notify(usize::MAX); @@ -145,7 +144,7 @@ impl WebSocketWrapper { .into(), ) } - .map_err(|x| EpoxyError::WebSocketConnectFailed(format!("{:?}", x)))?; + .map_err(|x| EpoxyError::WebSocketConnectFailed(format!("{x:?}")))?; ws.set_binary_type(BinaryType::Arraybuffer); ws.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); ws.set_onopen(Some(onopen.as_ref().unchecked_ref())); @@ -177,15 +176,15 @@ impl WebSocketWrapper { return false; } futures_util::select! { - _ = self.open_event.listen().fuse() => true, - _ = self.error_event.listen().fuse() => false, + () = self.open_event.listen().fuse() => true, + () = self.error_event.listen().fuse() => false, } } } impl WebSocketWrite for WebSocketWrapper { async fn wisp_write_frame(&mut self, frame: Frame<'_>) -> Result<(), WispError> { - use wisp_mux::ws::OpCode::*; + use wisp_mux::ws::OpCode::{Binary, Close, Text}; if self.closed.load(Ordering::Acquire) { return Err(WispError::WsImplSocketClosed); } @@ -193,7 +192,7 @@ impl WebSocketWrite for WebSocketWrapper { Binary | Text => self .inner .send_with_u8_array(&frame.payload) - .map_err(|x| WebSocketError::SendFailed(format!("{:?}", x)).into()), + .map_err(|x| WebSocketError::SendFailed(format!("{x:?}")).into()), Close => { let _ = self.inner.close(); Ok(()) @@ -205,7 +204,7 @@ impl WebSocketWrite for WebSocketWrapper { async fn wisp_close(&mut self) -> Result<(), WispError> { self.inner .close() - .map_err(|x| WebSocketError::CloseFailed(format!("{:?}", x)).into()) + .map_err(|x| WebSocketError::CloseFailed(format!("{x:?}")).into()) } } diff --git a/server/Cargo.toml b/server/Cargo.toml index f281d36..8ddd6bc 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -3,6 +3,9 @@ name = "epoxy-server" version = "2.0.0" edition = "2021" +[lints] +workspace = true + [dependencies] anyhow = "1.0.86" async-speed-limit = { version = "0.4.2", optional = true } diff --git a/simple-wisp-client/Cargo.toml b/simple-wisp-client/Cargo.toml index 646485c..a71c2aa 100644 --- a/simple-wisp-client/Cargo.toml +++ b/simple-wisp-client/Cargo.toml @@ -3,6 +3,9 @@ name = "simple-wisp-client" version = "1.0.0" edition = "2021" +[lints] +workspace = true + [dependencies] atomic-counter = "1.0.1" bytes = "1.7.1" diff --git a/wisp/Cargo.toml b/wisp/Cargo.toml index f85edc6..608ffd4 100644 --- a/wisp/Cargo.toml +++ b/wisp/Cargo.toml @@ -10,6 +10,9 @@ edition = "2021" keywords = ["websocket", "wisp", "multiplexor", "multiplexing", "stream"] categories = ["network-programming", "asynchronous", "web-programming::websocket", "wasm"] +[lints] +workspace = true + [dependencies] async-trait = "0.1.81" atomic_enum = "0.3.0" diff --git a/wisp/src/lib.rs b/wisp/src/lib.rs index 1d4dfef..bca979f 100644 --- a/wisp/src/lib.rs +++ b/wisp/src/lib.rs @@ -1,11 +1,5 @@ #![cfg_attr(docsrs, feature(doc_cfg))] -#![warn(clippy::pedantic)] #![deny(missing_docs, clippy::todo)] -#![allow( - clippy::must_use_candidate, - clippy::missing_errors_doc, - clippy::module_name_repetitions -)] //! A library for easily creating [Wisp] clients and servers. //!