From 855e981d2e5071b3f438ccdec5f4ed0878e73d2b Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 02:06:15 +0100 Subject: [PATCH 1/8] Add usage examples to public functions --- src/extractor.rs | 52 ++++++++++++++++++++++++++++++ src/push.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/extractor.rs b/src/extractor.rs index f315c46c..e4db03b4 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -34,6 +34,22 @@ impl MessageRequest { /// Retrieve shared state of type `T` if available. /// /// Returns `None` when no value of type `T` was registered. + /// + /// # Examples + /// + /// ``` + /// use std::{any::TypeId, collections::HashMap, sync::Arc}; + /// + /// use wireframe::extractor::{MessageRequest, SharedState}; + /// + /// let mut req = MessageRequest::default(); + /// req.app_data.insert( + /// TypeId::of::(), + /// Arc::new(5u32) as Arc, + /// ); + /// let val: Option> = req.state(); + /// assert_eq!(*val.unwrap(), 5); + /// ``` #[must_use] pub fn state(&self) -> Option> where @@ -58,12 +74,33 @@ impl Payload<'_> { /// /// Consumes up to `count` bytes from the front of the slice, ensuring we /// never slice beyond the available buffer. + /// + /// # Examples + /// + /// ``` + /// use wireframe::extractor::Payload; + /// + /// let mut payload = Payload { data: b"abcd" }; + /// payload.advance(2); + /// assert_eq!(payload.data, b"cd" as &[u8]); + /// ``` pub fn advance(&mut self, count: usize) { let n = count.min(self.data.len()); self.data = &self.data[n..]; } /// Returns the number of bytes remaining. + /// + /// # Examples + /// + /// ``` + /// use wireframe::extractor::Payload; + /// + /// let mut payload = Payload { data: b"bytes" }; + /// assert_eq!(payload.remaining(), 5); + /// payload.advance(2); + /// assert_eq!(payload.remaining(), 3); + /// ``` #[must_use] pub fn remaining(&self) -> usize { self.data.len() } } @@ -246,6 +283,21 @@ pub struct ConnectionInfo { impl ConnectionInfo { /// Returns the peer's socket address for the current connection, if available. + /// + /// # Examples + /// + /// ``` + /// use std::net::SocketAddr; + /// + /// use wireframe::extractor::{ConnectionInfo, FromMessageRequest, MessageRequest, Payload}; + /// + /// let req = MessageRequest { + /// peer_addr: Some("127.0.0.1:8080".parse::().unwrap()), + /// ..Default::default() + /// }; + /// let info = ConnectionInfo::from_message_request(&req, &mut Payload::default()).unwrap(); + /// assert_eq!(info.peer_addr(), req.peer_addr); + /// ``` #[must_use] pub fn peer_addr(&self) -> Option { self.peer_addr } } diff --git a/src/push.rs b/src/push.rs index aaeedef2..ba89fe14 100644 --- a/src/push.rs +++ b/src/push.rs @@ -63,6 +63,21 @@ impl PushHandle { /// # Errors /// /// Returns [`PushError::Closed`] if the receiving end has been dropped. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::{PushPriority, PushQueues}; + /// + /// #[tokio::main] + /// async fn main() { + /// let (mut queues, handle) = PushQueues::bounded(1, 1); + /// handle.push_high_priority(42u8).await.unwrap(); + /// let (priority, frame) = queues.recv().await.unwrap(); + /// assert_eq!(priority, PushPriority::High); + /// assert_eq!(frame, 42); + /// } + /// ``` pub async fn push_high_priority(&self, frame: F) -> Result<(), PushError> { self.0 .high_prio_tx @@ -78,6 +93,21 @@ impl PushHandle { /// # Errors /// /// Returns [`PushError::Closed`] if the receiving end has been dropped. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::{PushPriority, PushQueues}; + /// + /// #[tokio::main] + /// async fn main() { + /// let (mut queues, handle) = PushQueues::bounded(1, 1); + /// handle.push_low_priority(10u8).await.unwrap(); + /// let (priority, frame) = queues.recv().await.unwrap(); + /// assert_eq!(priority, PushPriority::Low); + /// assert_eq!(frame, 10); + /// } + /// ``` pub async fn push_low_priority(&self, frame: F) -> Result<(), PushError> { self.0 .low_prio_tx @@ -93,6 +123,21 @@ impl PushHandle { /// Returns [`PushError::QueueFull`] if the queue is full and the policy is /// [`PushPolicy::ReturnErrorIfFull`]. Returns [`PushError::Closed`] if the /// receiving end has been dropped. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::{PushPolicy, PushPriority, PushQueues}; + /// + /// #[tokio::main] + /// async fn main() { + /// let (mut queues, handle) = PushQueues::bounded(1, 1); + /// handle.push_high_priority(1u8).await.unwrap(); + /// let result = handle.try_push(2u8, PushPriority::High, PushPolicy::ReturnErrorIfFull); + /// assert!(result.is_err()); + /// let _ = queues.recv().await; + /// } + /// ``` pub fn try_push( &self, frame: F, @@ -131,6 +176,21 @@ pub struct PushQueues { impl PushQueues { /// Create a new set of queues with the specified bounds for each priority /// and return them along with a [`PushHandle`] for producers. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::{PushPriority, PushQueues}; + /// + /// #[tokio::main] + /// async fn main() { + /// let (mut queues, handle) = PushQueues::::bounded(1, 1); + /// handle.push_high_priority(7u8).await.unwrap(); + /// let (priority, frame) = queues.recv().await.unwrap(); + /// assert_eq!(priority, PushPriority::High); + /// assert_eq!(frame, 7); + /// } + /// ``` #[must_use] pub fn bounded(high_capacity: usize, low_capacity: usize) -> (Self, PushHandle) { let (high_tx, high_rx) = mpsc::channel(high_capacity); @@ -151,6 +211,21 @@ impl PushQueues { /// Receive the next frame, preferring high priority frames when available. /// /// Returns `None` when both queues are closed and empty. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::{PushPriority, PushQueues}; + /// + /// #[tokio::main] + /// async fn main() { + /// let (mut queues, handle) = PushQueues::bounded(1, 1); + /// handle.push_high_priority(2u8).await.unwrap(); + /// let (priority, frame) = queues.recv().await.unwrap(); + /// assert_eq!(priority, PushPriority::High); + /// assert_eq!(frame, 2); + /// } + /// ``` pub async fn recv(&mut self) -> Option<(PushPriority, F)> { tokio::select! { biased; @@ -163,6 +238,15 @@ impl PushQueues { /// /// This is primarily used in tests to release resources when no actor is /// draining the queues. + /// + /// # Examples + /// + /// ``` + /// use wireframe::push::PushQueues; + /// + /// let (mut queues, _handle) = PushQueues::::bounded(1, 1); + /// queues.close(); + /// ``` pub fn close(&mut self) { self.high_priority_rx.close(); self.low_priority_rx.close(); From 7f1dc7342e890f5aca67785da4cf703bc30248c3 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 02:28:12 +0100 Subject: [PATCH 2/8] Address review comments --- src/extractor.rs | 20 ++++++++++++-------- src/push.rs | 14 ++++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/extractor.rs b/src/extractor.rs index e4db03b4..ca9d02e6 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -38,15 +38,19 @@ impl MessageRequest { /// # Examples /// /// ``` - /// use std::{any::TypeId, collections::HashMap, sync::Arc}; - /// - /// use wireframe::extractor::{MessageRequest, SharedState}; + /// use wireframe::{ + /// app::WireframeApp, + /// extractor::{MessageRequest, SharedState}, + /// }; /// - /// let mut req = MessageRequest::default(); - /// req.app_data.insert( - /// TypeId::of::(), - /// Arc::new(5u32) as Arc, - /// ); + /// let _app = WireframeApp::new().unwrap().app_data(5u32); + /// // The framework populates the request with application data. + /// # use std::{any::TypeId, collections::HashMap, sync::Arc}; + /// # let mut req = MessageRequest::default(); + /// # req.app_data.insert( + /// # TypeId::of::(), + /// # Arc::new(5u32) as Arc, + /// # ); /// let val: Option> = req.state(); /// assert_eq!(*val.unwrap(), 5); /// ``` diff --git a/src/push.rs b/src/push.rs index ba89fe14..e4d324ad 100644 --- a/src/push.rs +++ b/src/push.rs @@ -66,7 +66,7 @@ impl PushHandle { /// /// # Examples /// - /// ``` + /// ```no_run /// use wireframe::push::{PushPriority, PushQueues}; /// /// #[tokio::main] @@ -96,7 +96,7 @@ impl PushHandle { /// /// # Examples /// - /// ``` + /// ```no_run /// use wireframe::push::{PushPriority, PushQueues}; /// /// #[tokio::main] @@ -126,15 +126,17 @@ impl PushHandle { /// /// # Examples /// - /// ``` + /// ```no_run /// use wireframe::push::{PushPolicy, PushPriority, PushQueues}; /// /// #[tokio::main] /// async fn main() { /// let (mut queues, handle) = PushQueues::bounded(1, 1); /// handle.push_high_priority(1u8).await.unwrap(); + /// use wireframe::push::PushError; + /// /// let result = handle.try_push(2u8, PushPriority::High, PushPolicy::ReturnErrorIfFull); - /// assert!(result.is_err()); + /// assert!(matches!(result, Err(PushError::QueueFull))); /// let _ = queues.recv().await; /// } /// ``` @@ -179,7 +181,7 @@ impl PushQueues { /// /// # Examples /// - /// ``` + /// ```no_run /// use wireframe::push::{PushPriority, PushQueues}; /// /// #[tokio::main] @@ -214,7 +216,7 @@ impl PushQueues { /// /// # Examples /// - /// ``` + /// ```no_run /// use wireframe::push::{PushPriority, PushQueues}; /// /// #[tokio::main] From d9f5aab796d227c15ee78c260897f71bedcdf7b6 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 03:45:52 +0100 Subject: [PATCH 3/8] Simplify async doc examples with tokio test --- src/extractor.rs | 12 ++++++------ src/push.rs | 35 +++++++++++++++++------------------ 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/extractor.rs b/src/extractor.rs index ca9d02e6..a4dd1a35 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -37,7 +37,7 @@ impl MessageRequest { /// /// # Examples /// - /// ``` + /// ```rust,no_run /// use wireframe::{ /// app::WireframeApp, /// extractor::{MessageRequest, SharedState}, @@ -81,7 +81,7 @@ impl Payload<'_> { /// /// # Examples /// - /// ``` + /// ```rust,no_run /// use wireframe::extractor::Payload; /// /// let mut payload = Payload { data: b"abcd" }; @@ -97,7 +97,7 @@ impl Payload<'_> { /// /// # Examples /// - /// ``` + /// ```rust,no_run /// use wireframe::extractor::Payload; /// /// let mut payload = Payload { data: b"bytes" }; @@ -140,7 +140,7 @@ impl SharedState { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use std::sync::Arc; /// /// use wireframe::extractor::SharedState; @@ -224,7 +224,7 @@ impl std::ops::Deref for SharedState { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use std::sync::Arc; /// /// use wireframe::extractor::SharedState; @@ -290,7 +290,7 @@ impl ConnectionInfo { /// /// # Examples /// - /// ``` + /// ```rust,no_run /// use std::net::SocketAddr; /// /// use wireframe::extractor::{ConnectionInfo, FromMessageRequest, MessageRequest, Payload}; diff --git a/src/push.rs b/src/push.rs index e4d324ad..1d7d75c7 100644 --- a/src/push.rs +++ b/src/push.rs @@ -66,11 +66,11 @@ impl PushHandle { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use wireframe::push::{PushPriority, PushQueues}; /// - /// #[tokio::main] - /// async fn main() { + /// #[tokio::test] + /// async fn example() { /// let (mut queues, handle) = PushQueues::bounded(1, 1); /// handle.push_high_priority(42u8).await.unwrap(); /// let (priority, frame) = queues.recv().await.unwrap(); @@ -96,11 +96,11 @@ impl PushHandle { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use wireframe::push::{PushPriority, PushQueues}; /// - /// #[tokio::main] - /// async fn main() { + /// #[tokio::test] + /// async fn example() { /// let (mut queues, handle) = PushQueues::bounded(1, 1); /// handle.push_low_priority(10u8).await.unwrap(); /// let (priority, frame) = queues.recv().await.unwrap(); @@ -126,14 +126,13 @@ impl PushHandle { /// /// # Examples /// - /// ```no_run - /// use wireframe::push::{PushPolicy, PushPriority, PushQueues}; + /// ```rust,no_run + /// use wireframe::push::{PushError, PushPolicy, PushPriority, PushQueues}; /// - /// #[tokio::main] - /// async fn main() { + /// #[tokio::test] + /// async fn example() { /// let (mut queues, handle) = PushQueues::bounded(1, 1); /// handle.push_high_priority(1u8).await.unwrap(); - /// use wireframe::push::PushError; /// /// let result = handle.try_push(2u8, PushPriority::High, PushPolicy::ReturnErrorIfFull); /// assert!(matches!(result, Err(PushError::QueueFull))); @@ -181,11 +180,11 @@ impl PushQueues { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use wireframe::push::{PushPriority, PushQueues}; /// - /// #[tokio::main] - /// async fn main() { + /// #[tokio::test] + /// async fn example() { /// let (mut queues, handle) = PushQueues::::bounded(1, 1); /// handle.push_high_priority(7u8).await.unwrap(); /// let (priority, frame) = queues.recv().await.unwrap(); @@ -216,11 +215,11 @@ impl PushQueues { /// /// # Examples /// - /// ```no_run + /// ```rust,no_run /// use wireframe::push::{PushPriority, PushQueues}; /// - /// #[tokio::main] - /// async fn main() { + /// #[tokio::test] + /// async fn example() { /// let (mut queues, handle) = PushQueues::bounded(1, 1); /// handle.push_high_priority(2u8).await.unwrap(); /// let (priority, frame) = queues.recv().await.unwrap(); @@ -243,7 +242,7 @@ impl PushQueues { /// /// # Examples /// - /// ``` + /// ```rust,no_run /// use wireframe::push::PushQueues; /// /// let (mut queues, _handle) = PushQueues::::bounded(1, 1); From 2fe55167f49d3e8e5debf3090fa56b6663b87b73 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 09:39:37 +0100 Subject: [PATCH 4/8] Add usage examples to public functions --- src/extractor.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/extractor.rs b/src/extractor.rs index a4dd1a35..f3b19bb7 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -73,6 +73,21 @@ pub struct Payload<'a> { pub data: &'a [u8], } +impl<'a> Payload<'a> { + /// Creates a new `Payload` from the provided byte slice. + /// + /// # Examples + /// + /// ```rust,no_run + /// use wireframe::extractor::Payload; + /// + /// let payload = Payload::new(b"data"); + /// assert_eq!(payload.data, b"data" as &[u8]); + /// ``` + #[must_use] + pub fn new(data: &'a [u8]) -> Self { Self { data } } +} + impl Payload<'_> { /// Advances the payload by `count` bytes. /// @@ -84,7 +99,7 @@ impl Payload<'_> { /// ```rust,no_run /// use wireframe::extractor::Payload; /// - /// let mut payload = Payload { data: b"abcd" }; + /// let mut payload = Payload::new(b"abcd"); /// payload.advance(2); /// assert_eq!(payload.data, b"cd" as &[u8]); /// ``` @@ -100,7 +115,7 @@ impl Payload<'_> { /// ```rust,no_run /// use wireframe::extractor::Payload; /// - /// let mut payload = Payload { data: b"bytes" }; + /// let mut payload = Payload::new(b"bytes"); /// assert_eq!(payload.remaining(), 5); /// payload.advance(2); /// assert_eq!(payload.remaining(), 3); From 655cce0fededefce8d5704aa80d4553309d75938 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 13:49:25 +0100 Subject: [PATCH 5/8] Implement From slice for Payload --- src/extractor.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/extractor.rs b/src/extractor.rs index f3b19bb7..c1e38561 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -67,6 +67,17 @@ impl MessageRequest { } /// Raw payload buffer handed to extractors. +/// +/// Create a `Payload` from a slice using [`Payload::new`] or `into`: +/// +/// ```rust +/// use wireframe::extractor::Payload; +/// +/// let p1 = Payload::new(b"abc"); +/// let p2: Payload<'_> = b"xyz".as_slice().into(); +/// assert_eq!(p1.data, b"abc" as &[u8]); +/// assert_eq!(p2.data, b"xyz" as &[u8]); +/// ``` #[derive(Default)] pub struct Payload<'a> { /// Incoming bytes not yet processed. @@ -88,6 +99,10 @@ impl<'a> Payload<'a> { pub fn new(data: &'a [u8]) -> Self { Self { data } } } +impl<'a> From<&'a [u8]> for Payload<'a> { + fn from(data: &'a [u8]) -> Self { Self { data } } +} + impl Payload<'_> { /// Advances the payload by `count` bytes. /// From 5b0e81ea0566261e16e5cf6b65d06b11cb07ad08 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 18:40:31 +0100 Subject: [PATCH 6/8] Add usage examples to public functions --- README.md | 4 ++-- src/extractor.rs | 46 ++++++++++++++++++++++++++++++++++++---------- tests/app_data.rs | 13 ++----------- tests/extractor.rs | 22 +++++----------------- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index acf8a719..f576f9f6 100644 --- a/README.md +++ b/README.md @@ -234,8 +234,8 @@ impl FromMessageRequest for SessionToken { _req: &MessageRequest, payload: &mut Payload<'_>, ) -> Result { - let len = payload.data[0] as usize; - let token = std::str::from_utf8(&payload.data[1..=len]).unwrap().to_string(); + let len = payload.as_ref()[0] as usize; + let token = std::str::from_utf8(&payload.as_ref()[1..=len]).unwrap().to_string(); payload.advance(1 + len); Ok(Self(token)) } diff --git a/src/extractor.rs b/src/extractor.rs index c1e38561..a0095e03 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -45,12 +45,8 @@ impl MessageRequest { /// /// let _app = WireframeApp::new().unwrap().app_data(5u32); /// // The framework populates the request with application data. - /// # use std::{any::TypeId, collections::HashMap, sync::Arc}; /// # let mut req = MessageRequest::default(); - /// # req.app_data.insert( - /// # TypeId::of::(), - /// # Arc::new(5u32) as Arc, - /// # ); + /// # req.insert_state(5u32); /// let val: Option> = req.state(); /// assert_eq!(*val.unwrap(), 5); /// ``` @@ -64,6 +60,30 @@ impl MessageRequest { .and_then(|data| data.clone().downcast::().ok()) .map(SharedState) } + + /// Insert shared state of type `T` into the request. + /// + /// This replaces any existing value of the same type. + /// + /// # Examples + /// + /// ```rust + /// use wireframe::extractor::{MessageRequest, SharedState}; + /// + /// let mut req = MessageRequest::default(); + /// req.insert_state(5u32); + /// let val: Option> = req.state(); + /// assert_eq!(*val.unwrap(), 5); + /// ``` + pub fn insert_state(&mut self, state: T) + where + T: Send + Sync + 'static, + { + self.app_data.insert( + TypeId::of::(), + Arc::new(state) as Arc, + ); + } } /// Raw payload buffer handed to extractors. @@ -75,13 +95,13 @@ impl MessageRequest { /// /// let p1 = Payload::new(b"abc"); /// let p2: Payload<'_> = b"xyz".as_slice().into(); -/// assert_eq!(p1.data, b"abc" as &[u8]); -/// assert_eq!(p2.data, b"xyz" as &[u8]); +/// assert_eq!(p1.as_ref(), b"abc" as &[u8]); +/// assert_eq!(p2.as_ref(), b"xyz" as &[u8]); /// ``` #[derive(Default)] pub struct Payload<'a> { /// Incoming bytes not yet processed. - pub data: &'a [u8], + data: &'a [u8], } impl<'a> Payload<'a> { @@ -93,16 +113,22 @@ impl<'a> Payload<'a> { /// use wireframe::extractor::Payload; /// /// let payload = Payload::new(b"data"); - /// assert_eq!(payload.data, b"data" as &[u8]); + /// assert_eq!(payload.as_ref(), b"data" as &[u8]); /// ``` #[must_use] + #[inline] pub fn new(data: &'a [u8]) -> Self { Self { data } } } impl<'a> From<&'a [u8]> for Payload<'a> { + #[inline] fn from(data: &'a [u8]) -> Self { Self { data } } } +impl AsRef<[u8]> for Payload<'_> { + fn as_ref(&self) -> &[u8] { self.data } +} + impl Payload<'_> { /// Advances the payload by `count` bytes. /// @@ -116,7 +142,7 @@ impl Payload<'_> { /// /// let mut payload = Payload::new(b"abcd"); /// payload.advance(2); - /// assert_eq!(payload.data, b"cd" as &[u8]); + /// assert_eq!(payload.as_ref(), b"cd" as &[u8]); /// ``` pub fn advance(&mut self, count: usize) { let n = count.min(self.data.len()); diff --git a/tests/app_data.rs b/tests/app_data.rs index 2000bf91..98900995 100644 --- a/tests/app_data.rs +++ b/tests/app_data.rs @@ -2,8 +2,6 @@ //! //! They verify successful extraction and error handling when state is missing. -use std::{any::TypeId, collections::HashMap, sync::Arc}; - use wireframe::extractor::{ ExtractError, FromMessageRequest, @@ -14,15 +12,8 @@ use wireframe::extractor::{ #[test] fn shared_state_extractor_returns_data() { - let mut map = HashMap::new(); - map.insert( - TypeId::of::(), - Arc::new(5u32) as Arc, - ); - let req = MessageRequest { - peer_addr: None, - app_data: map, - }; + let mut req = MessageRequest::default(); + req.insert_state(5u32); let mut payload = Payload::default(); let extracted = SharedState::::from_message_request(&req, &mut payload).unwrap(); assert_eq!(*extracted, 5); diff --git a/tests/extractor.rs b/tests/extractor.rs index 8b49774f..7be8fba9 100644 --- a/tests/extractor.rs +++ b/tests/extractor.rs @@ -2,7 +2,7 @@ //! //! Validate message parsing, connection info, and shared state behaviour. -use std::{collections::HashMap, net::SocketAddr}; +use std::net::SocketAddr; use wireframe::{ extractor::{ConnectionInfo, FromMessageRequest, Message, MessageRequest, Payload}, @@ -21,9 +21,7 @@ struct TestMsg(u8); fn message_extractor_parses_and_advances() { let msg = TestMsg(42); let bytes = msg.to_bytes().unwrap(); - let mut payload = Payload { - data: bytes.as_slice(), - }; + let mut payload = Payload::new(bytes.as_slice()); let req = MessageRequest::default(); let extracted = Message::::from_message_request(&req, &mut payload).unwrap(); @@ -36,10 +34,7 @@ fn message_extractor_parses_and_advances() { /// `MessageRequest`. fn connection_info_reports_peer() { let addr: SocketAddr = "127.0.0.1:12345".parse().unwrap(); - let req = MessageRequest { - peer_addr: Some(addr), - app_data: HashMap::default(), - }; + let req = MessageRequest { peer_addr: Some(addr), ..Default::default() }; let mut payload = Payload::default(); let info = ConnectionInfo::from_message_request(&req, &mut payload).unwrap(); assert_eq!(info.peer_addr(), Some(addr)); @@ -52,15 +47,8 @@ fn connection_info_reports_peer() { /// Inserts an `Arc` into the request's shared state, extracts it using the `SharedState` /// extractor, and asserts that the extracted value matches the original. fn shared_state_extractor() { - let mut data = HashMap::default(); - data.insert( - std::any::TypeId::of::(), - std::sync::Arc::new(42u8) as std::sync::Arc, - ); - let req = MessageRequest { - peer_addr: None, - app_data: data, - }; + let mut req = MessageRequest::default(); + req.insert_state(42u8); let mut payload = Payload::default(); let state = From e1f12738bba15c30db430f40cc6ce64f754e7e2d Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 19:28:51 +0100 Subject: [PATCH 7/8] Add usage examples to public functions --- tests/extractor.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/extractor.rs b/tests/extractor.rs index 7be8fba9..a9f8ec5b 100644 --- a/tests/extractor.rs +++ b/tests/extractor.rs @@ -34,7 +34,10 @@ fn message_extractor_parses_and_advances() { /// `MessageRequest`. fn connection_info_reports_peer() { let addr: SocketAddr = "127.0.0.1:12345".parse().unwrap(); - let req = MessageRequest { peer_addr: Some(addr), ..Default::default() }; + let req = MessageRequest { + peer_addr: Some(addr), + ..Default::default() + }; let mut payload = Payload::default(); let info = ConnectionInfo::from_message_request(&req, &mut payload).unwrap(); assert_eq!(info.peer_addr(), Some(addr)); From 8d9cf59ac3df05494e90d85c3c5eccd06dd1a2f5 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 4 Jul 2025 19:37:20 +0100 Subject: [PATCH 8/8] Give the parse failure a diagnostic message Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- tests/extractor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/extractor.rs b/tests/extractor.rs index a9f8ec5b..2f1564c3 100644 --- a/tests/extractor.rs +++ b/tests/extractor.rs @@ -33,7 +33,9 @@ fn message_extractor_parses_and_advances() { /// Tests that `ConnectionInfo` correctly reports the peer socket address extracted from a /// `MessageRequest`. fn connection_info_reports_peer() { - let addr: SocketAddr = "127.0.0.1:12345".parse().unwrap(); + let addr: SocketAddr = "127.0.0.1:12345" + .parse() + .expect("hard-coded socket address must be valid"); let req = MessageRequest { peer_addr: Some(addr), ..Default::default()