From 0a7e6b8ecbc5d8ead976a5cd10a2a89e406ca6ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Jun 2025 21:35:51 +0000 Subject: [PATCH 1/5] Initial plan for issue From a0308e06da3215b75f84ae644e1f94669d67ff15 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Jun 2025 21:48:48 +0000 Subject: [PATCH 2/5] Implement metadata support for network interfaces Co-authored-by: jaybosamiya-ms <171180729+jaybosamiya-ms@users.noreply.github.com> --- litebox/src/net/errors.rs | 18 +++++ litebox/src/net/mod.rs | 98 ++++++++++++++++++++++++++- litebox/src/net/tests.rs | 139 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 2 deletions(-) diff --git a/litebox/src/net/errors.rs b/litebox/src/net/errors.rs index e15e6db8b..7686b697d 100644 --- a/litebox/src/net/errors.rs +++ b/litebox/src/net/errors.rs @@ -109,3 +109,21 @@ pub enum SetTcpOptionError { #[error("Not a TCP socket")] NotTcpSocket, } + +/// Possible errors from [`Network::with_metadata`] and [`Network::with_metadata_mut`] +#[non_exhaustive] +#[derive(Error, Debug)] +pub enum MetadataError { + #[error("Not a valid open file descriptor")] + InvalidFd, + #[error("no such metadata available")] + NoSuchMetadata, +} + +/// Possible errors from [`Network::set_socket_metadata`] and [`Network::set_fd_metadata`] +#[non_exhaustive] +#[derive(Error, Debug)] +pub enum SetMetadataError { + #[error("Not a valid open file descriptor")] + InvalidFd(T), +} diff --git a/litebox/src/net/mod.rs b/litebox/src/net/mod.rs index 756a479dd..bc3fdfeb6 100644 --- a/litebox/src/net/mod.rs +++ b/litebox/src/net/mod.rs @@ -9,6 +9,7 @@ use crate::fd::InternalFd; use crate::platform::Instant; use crate::{LiteBox, platform, sync}; use crate::{event::EventManager, fd::SocketFd}; +use crate::utilities::anymap::AnyMap; use bitflags::bitflags; use smoltcp::socket::{icmp, raw, tcp, udp}; @@ -21,8 +22,8 @@ mod phy; mod tests; use errors::{ - AcceptError, BindError, CloseError, ConnectError, ListenError, ReceiveError, SendError, - SocketError, + AcceptError, BindError, CloseError, ConnectError, ListenError, MetadataError, ReceiveError, + SendError, SetMetadataError, SocketError, }; use local_ports::{LocalPort, LocalPortAllocator}; @@ -134,6 +135,10 @@ struct SocketHandle { handle: smoltcp::iface::SocketHandle, // Protocol-specific data specific: ProtocolSpecific, + /// Socket-level metadata (shared across all FDs to the same socket) + socket_metadata: AnyMap, + /// FD-specific metadata (specific to this file descriptor) + fd_metadata: AnyMap, } impl core::ops::Deref for SocketHandle { @@ -541,6 +546,8 @@ where Protocol::Icmp => unimplemented!(), Protocol::Raw { protocol } => unimplemented!(), }, + socket_metadata: AnyMap::new(), + fd_metadata: AnyMap::new(), })) } @@ -807,6 +814,8 @@ where local_port, server_socket: None, }), + socket_metadata: AnyMap::new(), + fd_metadata: AnyMap::new(), })) } ProtocolSpecific::Udp(_) => unimplemented!(), @@ -907,6 +916,91 @@ where } } } + + /// Apply `f` on metadata at a socket fd, if it exists. + /// + /// This returns the most-specific metadata available for the socket file descriptor---specifically, if + /// both [`Self::set_fd_metadata`] and [`Self::set_socket_metadata`] are run on the same fd, this + /// will only return the value from the fd one, which will shadow the socket one. If no + /// fd-specific one is set, this returns the socket-specific one. + pub fn with_metadata( + &self, + fd: &SocketFd, + f: impl FnOnce(&T) -> R, + ) -> Result { + let socket_handle = match self.handles.get(fd.x.as_usize()) { + Some(Some(handle)) => handle, + _ => return Err(MetadataError::InvalidFd), + }; + + // First check fd-specific metadata, then socket-specific metadata + if let Some(m) = socket_handle.fd_metadata.get::() { + Ok(f(m)) + } else if let Some(m) = socket_handle.socket_metadata.get::() { + Ok(f(m)) + } else { + Err(MetadataError::NoSuchMetadata) + } + } + + /// Similar to [`Self::with_metadata`] but mutable. + pub fn with_metadata_mut( + &mut self, + fd: &SocketFd, + f: impl FnOnce(&mut T) -> R, + ) -> Result { + let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { + Some(Some(handle)) => handle, + _ => return Err(MetadataError::InvalidFd), + }; + + // First check fd-specific metadata, then socket-specific metadata + if let Some(m) = socket_handle.fd_metadata.get_mut::() { + Ok(f(m)) + } else if let Some(m) = socket_handle.socket_metadata.get_mut::() { + Ok(f(m)) + } else { + Err(MetadataError::NoSuchMetadata) + } + } + + /// Store arbitrary metadata into a socket. + /// + /// Such metadata is visible to any open file descriptor on the socket associated with the socket + /// file descriptor. See similar [`Self::set_fd_metadata`] which is specific to file descriptors, and + /// does not alias the metadata. + /// + /// Returns the old metadata if any such metadata exists. + pub fn set_socket_metadata( + &mut self, + fd: &SocketFd, + metadata: T, + ) -> Result, SetMetadataError> { + let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { + Some(Some(handle)) => handle, + _ => return Err(SetMetadataError::InvalidFd(metadata)), + }; + + Ok(socket_handle.socket_metadata.insert(metadata)) + } + + /// Store arbitrary metadata into a socket file descriptor. + /// + /// Such metadata is specific to the current file descriptor and is NOT shared with other open + /// descriptors to the same socket. See the similar [`Self::set_socket_metadata`] which aliases + /// metadata over all file descriptors opened for the same socket. + pub fn set_fd_metadata( + &mut self, + fd: &SocketFd, + metadata: T, + ) -> Result, SetMetadataError> { + let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { + Some(Some(handle)) => handle, + _ => return Err(SetMetadataError::InvalidFd(metadata)), + }; + + Ok(socket_handle.fd_metadata.insert(metadata)) + } } /// Protocols for sockets supported by LiteBox diff --git a/litebox/src/net/tests.rs b/litebox/src/net/tests.rs index cf4746d14..1ca7986fc 100644 --- a/litebox/src/net/tests.rs +++ b/litebox/src/net/tests.rs @@ -4,6 +4,7 @@ use super::*; use core::net::SocketAddrV4; use core::str::FromStr; +use alloc::string::String; extern crate std; @@ -97,3 +98,141 @@ fn test_bidirectional_tcp_communication_automatic() { network.set_platform_interaction(PlatformInteraction::Automatic); bidi_tcp_comms(network, |_| {}); } + +#[test] +fn test_socket_metadata() { + let litebox = LiteBox::new(MockPlatform::new()); + let mut network = Network::new(&litebox); + + // Create a socket + let socket_fd = network + .socket(Protocol::Tcp) + .expect("Failed to create TCP socket"); + + // Test setting and getting socket metadata + let test_data = String::from("socket-level metadata"); + let old_metadata = network + .set_socket_metadata(&socket_fd, test_data.clone()) + .expect("Failed to set socket metadata"); + assert!(old_metadata.is_none(), "Expected no previous metadata"); + + // Test reading socket metadata + let retrieved_data = network + .with_metadata(&socket_fd, |data: &String| data.clone()) + .expect("Failed to get socket metadata"); + assert_eq!(retrieved_data, test_data, "Retrieved metadata should match"); + + // Test overwriting socket metadata + let new_test_data = String::from("updated socket metadata"); + let old_metadata = network + .set_socket_metadata(&socket_fd, new_test_data.clone()) + .expect("Failed to update socket metadata"); + assert_eq!( + old_metadata, Some(test_data), + "Should return previous metadata" + ); + + // Test retrieving updated metadata + let updated_data = network + .with_metadata(&socket_fd, |data: &String| data.clone()) + .expect("Failed to get updated socket metadata"); + assert_eq!(updated_data, new_test_data, "Updated metadata should match"); + + // Close the socket + network.close(socket_fd).expect("Failed to close socket"); +} + +#[test] +fn test_fd_metadata() { + let litebox = LiteBox::new(MockPlatform::new()); + let mut network = Network::new(&litebox); + + // Create a socket + let socket_fd = network + .socket(Protocol::Tcp) + .expect("Failed to create TCP socket"); + + // Test setting and getting fd-specific metadata + let test_data = 42u32; + let old_metadata = network + .set_fd_metadata(&socket_fd, test_data) + .expect("Failed to set fd metadata"); + assert!(old_metadata.is_none(), "Expected no previous metadata"); + + // Test reading fd metadata + let retrieved_data = network + .with_metadata(&socket_fd, |data: &u32| *data) + .expect("Failed to get fd metadata"); + assert_eq!(retrieved_data, test_data, "Retrieved metadata should match"); + + // Test that mutable access works + network + .with_metadata_mut(&socket_fd, |data: &mut u32| { + *data += 1; + }) + .expect("Failed to modify fd metadata"); + + let modified_data = network + .with_metadata(&socket_fd, |data: &u32| *data) + .expect("Failed to get modified fd metadata"); + assert_eq!(modified_data, test_data + 1, "Modified metadata should be incremented"); + + // Close the socket + network.close(socket_fd).expect("Failed to close socket"); +} + +#[test] +fn test_metadata_priority() { + let litebox = LiteBox::new(MockPlatform::new()); + let mut network = Network::new(&litebox); + + // Create a socket + let socket_fd = network + .socket(Protocol::Tcp) + .expect("Failed to create TCP socket"); + + // Set socket-level metadata + let socket_data = String::from("socket level"); + network + .set_socket_metadata(&socket_fd, socket_data.clone()) + .expect("Failed to set socket metadata"); + + // Verify socket metadata is accessible + let retrieved_socket_data = network + .with_metadata(&socket_fd, |data: &String| data.clone()) + .expect("Failed to get socket metadata"); + assert_eq!(retrieved_socket_data, socket_data, "Socket metadata should match"); + + // Set fd-level metadata of the same type - this should shadow socket metadata + let fd_data = String::from("fd level"); + network + .set_fd_metadata(&socket_fd, fd_data.clone()) + .expect("Failed to set fd metadata"); + + // Verify fd metadata shadows socket metadata + let retrieved_data = network + .with_metadata(&socket_fd, |data: &String| data.clone()) + .expect("Failed to get metadata"); + assert_eq!(retrieved_data, fd_data, "FD metadata should shadow socket metadata"); + + // Close the socket + network.close(socket_fd).expect("Failed to close socket"); +} + +#[test] +fn test_metadata_errors() { + let litebox = LiteBox::new(MockPlatform::new()); + let mut network = Network::new(&litebox); + + // Create a socket + let socket_fd = network + .socket(Protocol::Tcp) + .expect("Failed to create TCP socket"); + + // Test nonexistent metadata type + let result = network.with_metadata(&socket_fd, |_data: &String| ()); + assert!(matches!(result, Err(MetadataError::NoSuchMetadata)), "Should return NoSuchMetadata error"); + + // Close the socket + network.close(socket_fd).expect("Failed to close socket"); +} From 95e40baea96e04f18422c668cd3b62bfc0ceec76 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Jun 2025 23:32:27 +0000 Subject: [PATCH 3/5] Address feedback: Remove FD-specific metadata, keep only socket-level metadata - Remove InvalidFd from MetadataError and SetMetadataError - Remove fd_metadata field from SocketHandle - Remove set_fd_metadata method entirely - Update metadata methods to only work with socket_metadata - Remove test_fd_metadata and test_metadata_priority tests - Add TODO comments linking to #120 and #31 for future FD-specific metadata - Keep SetMetadataError as non-exhaustive but empty enum with phantom type Co-authored-by: jaybosamiya-ms <171180729+jaybosamiya-ms@users.noreply.github.com> --- litebox/src/net/errors.rs | 9 ++-- litebox/src/net/mod.rs | 66 ++++++++++------------------- litebox/src/net/tests.rs | 89 ++++----------------------------------- 3 files changed, 34 insertions(+), 130 deletions(-) diff --git a/litebox/src/net/errors.rs b/litebox/src/net/errors.rs index 7686b697d..ff05a415f 100644 --- a/litebox/src/net/errors.rs +++ b/litebox/src/net/errors.rs @@ -114,16 +114,15 @@ pub enum SetTcpOptionError { #[non_exhaustive] #[derive(Error, Debug)] pub enum MetadataError { - #[error("Not a valid open file descriptor")] - InvalidFd, #[error("no such metadata available")] NoSuchMetadata, } -/// Possible errors from [`Network::set_socket_metadata`] and [`Network::set_fd_metadata`] +/// Possible errors from [`Network::set_socket_metadata`] #[non_exhaustive] #[derive(Error, Debug)] pub enum SetMetadataError { - #[error("Not a valid open file descriptor")] - InvalidFd(T), + // Note: we return the T just so we are not dropping data + #[doc(hidden)] + _Phantom(core::marker::PhantomData), } diff --git a/litebox/src/net/mod.rs b/litebox/src/net/mod.rs index bc3fdfeb6..f4dfc5114 100644 --- a/litebox/src/net/mod.rs +++ b/litebox/src/net/mod.rs @@ -7,9 +7,9 @@ use core::net::{Ipv4Addr, SocketAddr}; use crate::event::Events; use crate::fd::InternalFd; use crate::platform::Instant; +use crate::utilities::anymap::AnyMap; use crate::{LiteBox, platform, sync}; use crate::{event::EventManager, fd::SocketFd}; -use crate::utilities::anymap::AnyMap; use bitflags::bitflags; use smoltcp::socket::{icmp, raw, tcp, udp}; @@ -135,10 +135,11 @@ struct SocketHandle { handle: smoltcp::iface::SocketHandle, // Protocol-specific data specific: ProtocolSpecific, - /// Socket-level metadata (shared across all FDs to the same socket) + /// Socket-level metadata + /// TODO: FD-specific metadata (similar to fs) will be added in the future. + /// This needs to be handled when switching to the Arc-based implementation + /// (possibly connected to #31) and is tracked in #120. socket_metadata: AnyMap, - /// FD-specific metadata (specific to this file descriptor) - fd_metadata: AnyMap, } impl core::ops::Deref for SocketHandle { @@ -547,7 +548,6 @@ where Protocol::Raw { protocol } => unimplemented!(), }, socket_metadata: AnyMap::new(), - fd_metadata: AnyMap::new(), })) } @@ -815,7 +815,6 @@ where server_socket: None, }), socket_metadata: AnyMap::new(), - fd_metadata: AnyMap::new(), })) } ProtocolSpecific::Udp(_) => unimplemented!(), @@ -918,11 +917,6 @@ where } /// Apply `f` on metadata at a socket fd, if it exists. - /// - /// This returns the most-specific metadata available for the socket file descriptor---specifically, if - /// both [`Self::set_fd_metadata`] and [`Self::set_socket_metadata`] are run on the same fd, this - /// will only return the value from the fd one, which will shadow the socket one. If no - /// fd-specific one is set, this returns the socket-specific one. pub fn with_metadata( &self, fd: &SocketFd, @@ -930,13 +924,13 @@ where ) -> Result { let socket_handle = match self.handles.get(fd.x.as_usize()) { Some(Some(handle)) => handle, - _ => return Err(MetadataError::InvalidFd), + _ => { + // This should not happen due to borrow checking, but handle gracefully + return Err(MetadataError::NoSuchMetadata); + } }; - // First check fd-specific metadata, then socket-specific metadata - if let Some(m) = socket_handle.fd_metadata.get::() { - Ok(f(m)) - } else if let Some(m) = socket_handle.socket_metadata.get::() { + if let Some(m) = socket_handle.socket_metadata.get::() { Ok(f(m)) } else { Err(MetadataError::NoSuchMetadata) @@ -951,13 +945,13 @@ where ) -> Result { let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { Some(Some(handle)) => handle, - _ => return Err(MetadataError::InvalidFd), + _ => { + // This should not happen due to borrow checking, but handle gracefully + return Err(MetadataError::NoSuchMetadata); + } }; - // First check fd-specific metadata, then socket-specific metadata - if let Some(m) = socket_handle.fd_metadata.get_mut::() { - Ok(f(m)) - } else if let Some(m) = socket_handle.socket_metadata.get_mut::() { + if let Some(m) = socket_handle.socket_metadata.get_mut::() { Ok(f(m)) } else { Err(MetadataError::NoSuchMetadata) @@ -966,10 +960,6 @@ where /// Store arbitrary metadata into a socket. /// - /// Such metadata is visible to any open file descriptor on the socket associated with the socket - /// file descriptor. See similar [`Self::set_fd_metadata`] which is specific to file descriptors, and - /// does not alias the metadata. - /// /// Returns the old metadata if any such metadata exists. pub fn set_socket_metadata( &mut self, @@ -978,29 +968,17 @@ where ) -> Result, SetMetadataError> { let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { Some(Some(handle)) => handle, - _ => return Err(SetMetadataError::InvalidFd(metadata)), + _ => { + // This should not happen due to borrow checking, but handle gracefully + // We construct a phantom error since the error type must be non-empty for now + unreachable!( + "Invalid file descriptor access should be prevented by borrow checking" + ); + } }; Ok(socket_handle.socket_metadata.insert(metadata)) } - - /// Store arbitrary metadata into a socket file descriptor. - /// - /// Such metadata is specific to the current file descriptor and is NOT shared with other open - /// descriptors to the same socket. See the similar [`Self::set_socket_metadata`] which aliases - /// metadata over all file descriptors opened for the same socket. - pub fn set_fd_metadata( - &mut self, - fd: &SocketFd, - metadata: T, - ) -> Result, SetMetadataError> { - let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { - Some(Some(handle)) => handle, - _ => return Err(SetMetadataError::InvalidFd(metadata)), - }; - - Ok(socket_handle.fd_metadata.insert(metadata)) - } } /// Protocols for sockets supported by LiteBox diff --git a/litebox/src/net/tests.rs b/litebox/src/net/tests.rs index 1ca7986fc..d9b4158c4 100644 --- a/litebox/src/net/tests.rs +++ b/litebox/src/net/tests.rs @@ -2,9 +2,9 @@ use platform::mock::MockPlatform; use super::*; +use alloc::string::String; use core::net::SocketAddrV4; use core::str::FromStr; -use alloc::string::String; extern crate std; @@ -128,7 +128,8 @@ fn test_socket_metadata() { .set_socket_metadata(&socket_fd, new_test_data.clone()) .expect("Failed to update socket metadata"); assert_eq!( - old_metadata, Some(test_data), + old_metadata, + Some(test_data), "Should return previous metadata" ); @@ -142,96 +143,22 @@ fn test_socket_metadata() { network.close(socket_fd).expect("Failed to close socket"); } -#[test] -fn test_fd_metadata() { - let litebox = LiteBox::new(MockPlatform::new()); - let mut network = Network::new(&litebox); - - // Create a socket - let socket_fd = network - .socket(Protocol::Tcp) - .expect("Failed to create TCP socket"); - - // Test setting and getting fd-specific metadata - let test_data = 42u32; - let old_metadata = network - .set_fd_metadata(&socket_fd, test_data) - .expect("Failed to set fd metadata"); - assert!(old_metadata.is_none(), "Expected no previous metadata"); - - // Test reading fd metadata - let retrieved_data = network - .with_metadata(&socket_fd, |data: &u32| *data) - .expect("Failed to get fd metadata"); - assert_eq!(retrieved_data, test_data, "Retrieved metadata should match"); - - // Test that mutable access works - network - .with_metadata_mut(&socket_fd, |data: &mut u32| { - *data += 1; - }) - .expect("Failed to modify fd metadata"); - - let modified_data = network - .with_metadata(&socket_fd, |data: &u32| *data) - .expect("Failed to get modified fd metadata"); - assert_eq!(modified_data, test_data + 1, "Modified metadata should be incremented"); - - // Close the socket - network.close(socket_fd).expect("Failed to close socket"); -} - -#[test] -fn test_metadata_priority() { - let litebox = LiteBox::new(MockPlatform::new()); - let mut network = Network::new(&litebox); - - // Create a socket - let socket_fd = network - .socket(Protocol::Tcp) - .expect("Failed to create TCP socket"); - - // Set socket-level metadata - let socket_data = String::from("socket level"); - network - .set_socket_metadata(&socket_fd, socket_data.clone()) - .expect("Failed to set socket metadata"); - - // Verify socket metadata is accessible - let retrieved_socket_data = network - .with_metadata(&socket_fd, |data: &String| data.clone()) - .expect("Failed to get socket metadata"); - assert_eq!(retrieved_socket_data, socket_data, "Socket metadata should match"); - - // Set fd-level metadata of the same type - this should shadow socket metadata - let fd_data = String::from("fd level"); - network - .set_fd_metadata(&socket_fd, fd_data.clone()) - .expect("Failed to set fd metadata"); - - // Verify fd metadata shadows socket metadata - let retrieved_data = network - .with_metadata(&socket_fd, |data: &String| data.clone()) - .expect("Failed to get metadata"); - assert_eq!(retrieved_data, fd_data, "FD metadata should shadow socket metadata"); - - // Close the socket - network.close(socket_fd).expect("Failed to close socket"); -} - #[test] fn test_metadata_errors() { let litebox = LiteBox::new(MockPlatform::new()); let mut network = Network::new(&litebox); - // Create a socket + // Create a socket let socket_fd = network .socket(Protocol::Tcp) .expect("Failed to create TCP socket"); // Test nonexistent metadata type let result = network.with_metadata(&socket_fd, |_data: &String| ()); - assert!(matches!(result, Err(MetadataError::NoSuchMetadata)), "Should return NoSuchMetadata error"); + assert!( + matches!(result, Err(MetadataError::NoSuchMetadata)), + "Should return NoSuchMetadata error" + ); // Close the socket network.close(socket_fd).expect("Failed to close socket"); From 66b3c20117972d8c9ebf06d4ea94a230d026bcde Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Jun 2025 01:14:30 +0000 Subject: [PATCH 4/5] Add InvalidFd back to metadata errors for consistency Co-authored-by: jaybosamiya-ms <171180729+jaybosamiya-ms@users.noreply.github.com> --- litebox/src/net/errors.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/litebox/src/net/errors.rs b/litebox/src/net/errors.rs index ff05a415f..89bf54451 100644 --- a/litebox/src/net/errors.rs +++ b/litebox/src/net/errors.rs @@ -114,6 +114,8 @@ pub enum SetTcpOptionError { #[non_exhaustive] #[derive(Error, Debug)] pub enum MetadataError { + #[error("Not a valid open file descriptor")] + InvalidFd, #[error("no such metadata available")] NoSuchMetadata, } @@ -122,7 +124,9 @@ pub enum MetadataError { #[non_exhaustive] #[derive(Error, Debug)] pub enum SetMetadataError { - // Note: we return the T just so we are not dropping data + #[error("Not a valid open file descriptor")] + InvalidFd(T), // Note: we return the T just so we are not dropping data #[doc(hidden)] + #[error("internal phantom type")] _Phantom(core::marker::PhantomData), } From b37ced8b261414dcab2ce6d9aad9615ed1c355a6 Mon Sep 17 00:00:00 2001 From: Jay Bosamiya Date: Fri, 20 Jun 2025 18:32:23 -0700 Subject: [PATCH 5/5] Refactor error handling for socket metadata access. --- litebox/src/net/errors.rs | 6 ++---- litebox/src/net/mod.rs | 31 ++++++++----------------------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/litebox/src/net/errors.rs b/litebox/src/net/errors.rs index 89bf54451..028112c39 100644 --- a/litebox/src/net/errors.rs +++ b/litebox/src/net/errors.rs @@ -125,8 +125,6 @@ pub enum MetadataError { #[derive(Error, Debug)] pub enum SetMetadataError { #[error("Not a valid open file descriptor")] - InvalidFd(T), // Note: we return the T just so we are not dropping data - #[doc(hidden)] - #[error("internal phantom type")] - _Phantom(core::marker::PhantomData), + // Note: we return the T just so we are not dropping data + InvalidFd(T), } diff --git a/litebox/src/net/mod.rs b/litebox/src/net/mod.rs index f4dfc5114..15d815292 100644 --- a/litebox/src/net/mod.rs +++ b/litebox/src/net/mod.rs @@ -922,13 +922,9 @@ where fd: &SocketFd, f: impl FnOnce(&T) -> R, ) -> Result { - let socket_handle = match self.handles.get(fd.x.as_usize()) { - Some(Some(handle)) => handle, - _ => { - // This should not happen due to borrow checking, but handle gracefully - return Err(MetadataError::NoSuchMetadata); - } - }; + let socket_handle = self.handles[fd.x.as_usize()] + .as_ref() + .ok_or(MetadataError::InvalidFd)?; if let Some(m) = socket_handle.socket_metadata.get::() { Ok(f(m)) @@ -943,13 +939,9 @@ where fd: &SocketFd, f: impl FnOnce(&mut T) -> R, ) -> Result { - let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { - Some(Some(handle)) => handle, - _ => { - // This should not happen due to borrow checking, but handle gracefully - return Err(MetadataError::NoSuchMetadata); - } - }; + let socket_handle = self.handles[fd.x.as_usize()] + .as_mut() + .ok_or(MetadataError::InvalidFd)?; if let Some(m) = socket_handle.socket_metadata.get_mut::() { Ok(f(m)) @@ -966,15 +958,8 @@ where fd: &SocketFd, metadata: T, ) -> Result, SetMetadataError> { - let socket_handle = match self.handles.get_mut(fd.x.as_usize()) { - Some(Some(handle)) => handle, - _ => { - // This should not happen due to borrow checking, but handle gracefully - // We construct a phantom error since the error type must be non-empty for now - unreachable!( - "Invalid file descriptor access should be prevented by borrow checking" - ); - } + let Some(socket_handle) = self.handles[fd.x.as_usize()].as_mut() else { + return Err(SetMetadataError::InvalidFd(metadata)); }; Ok(socket_handle.socket_metadata.insert(metadata))