From 4c00178ca35e76690c8fcd78cbd6269a98e814c0 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Tue, 5 Aug 2025 11:16:12 +0200 Subject: [PATCH 1/6] Unify error handling to have IpcError and TryRecvError be the main error types. These types will give the Bincode error, Io errors (which are converted from platform errors) and Disconnect. Additionally we now use the thiserror crate which removes some of the code. Signed-off-by: Narfinger --- Cargo.toml | 1 + src/asynch.rs | 3 +- src/error.rs | 32 +++++++++++++++ src/ipc.rs | 73 ++++++---------------------------- src/lib.rs | 3 +- src/platform/inprocess/mod.rs | 44 +++++++-------------- src/platform/macos/mod.rs | 74 +++++++++++------------------------ src/platform/unix/mod.rs | 46 ++++++++++------------ src/platform/windows/mod.rs | 38 ++++++++---------- src/router.rs | 11 +++--- src/test.rs | 14 +++---- 11 files changed, 135 insertions(+), 204 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.toml b/Cargo.toml index ffde680d..73dec714 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ futures-channel = { version = "0.3.31", optional = true } futures-core = { version = "0.3.31", optional = true } libc = "0.2.162" serde_core = "1.0" +thiserror = "2.0.12" uuid = { version = "1", features = ["v4"] } [target.'cfg(any(target_os = "linux", target_os = "openbsd", target_os = "freebsd", target_os = "illumos"))'.dependencies] diff --git a/src/asynch.rs b/src/asynch.rs index d0d3e183..a27904b6 100644 --- a/src/asynch.rs +++ b/src/asynch.rs @@ -7,6 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use crate::error::SerializationError; use crate::ipc::{ self, IpcMessage, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender, OpaqueIpcReceiver, }; @@ -95,7 +96,7 @@ impl Stream for IpcStream where T: for<'de> Deserialize<'de> + Serialize, { - type Item = Result; + type Item = Result; fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { let recv = Pin::new(&mut self.0); diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000..0a3292a1 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,32 @@ +use std::fmt::Display; +use std::io; + +use thiserror::Error; + +#[derive(Debug, Error)] +/// An error that occurs for serialization or deserialization +pub struct SerializationError(#[from] pub(crate) bincode::Error); + +impl Display for SerializationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Serialization error") + } +} + +#[derive(Debug, Error)] +pub enum IpcError { + #[error("Error in decoding or encoding: {0}")] + SerializationError(#[from] SerializationError), + #[error("Error in IO: {0}")] + Io(#[from] io::Error), + #[error("Ipc Disconnected")] + Disconnected, +} + +#[derive(Debug, Error)] +pub enum TryRecvError { + #[error("IPC error")] + IpcError(#[from] IpcError), + #[error("Channel empty")] + Empty, +} diff --git a/src/ipc.rs b/src/ipc.rs index ad43696d..8af5f814 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -7,16 +7,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use crate::error::SerializationError; use crate::platform::{self, OsIpcChannel, OsIpcReceiver, OsIpcReceiverSet, OsIpcSender}; use crate::platform::{ OsIpcOneShotServer, OsIpcSelectionResult, OsIpcSharedMemory, OsOpaqueIpcChannel, }; +use crate::{IpcError, TryRecvError}; use bincode; use serde_core::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use std::cell::RefCell; use std::cmp::min; -use std::error::Error as StdError; use std::fmt::{self, Debug, Formatter}; use std::io; use std::marker::PhantomData; @@ -36,57 +37,6 @@ thread_local! { const { RefCell::new(Vec::new()) } } -#[derive(Debug)] -pub enum IpcError { - Bincode(bincode::Error), - Io(io::Error), - Disconnected, -} - -impl fmt::Display for IpcError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - IpcError::Bincode(ref err) => write!(fmt, "bincode error: {err}"), - IpcError::Io(ref err) => write!(fmt, "io error: {err}"), - IpcError::Disconnected => write!(fmt, "disconnected"), - } - } -} - -impl StdError for IpcError { - fn source(&self) -> Option<&(dyn StdError + 'static)> { - match *self { - IpcError::Bincode(ref err) => Some(err), - IpcError::Io(ref err) => Some(err), - IpcError::Disconnected => None, - } - } -} - -#[derive(Debug)] -pub enum TryRecvError { - IpcError(IpcError), - Empty, -} - -impl fmt::Display for TryRecvError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - TryRecvError::IpcError(ref err) => write!(fmt, "ipc error: {err}"), - TryRecvError::Empty => write!(fmt, "empty"), - } - } -} - -impl StdError for TryRecvError { - fn source(&self) -> Option<&(dyn StdError + 'static)> { - match *self { - TryRecvError::IpcError(ref err) => Some(err), - TryRecvError::Empty => None, - } - } -} - /// Create a connected [IpcSender] and [IpcReceiver] that /// transfer messages of a given type provided by type `T` /// or inferred by the types of messages sent by the sender. @@ -247,7 +197,10 @@ where { /// Blocking receive. pub fn recv(&self) -> Result { - self.os_receiver.recv()?.to().map_err(IpcError::Bincode) + self.os_receiver + .recv()? + .to() + .map_err(IpcError::SerializationError) } /// Non-blocking receive @@ -255,7 +208,7 @@ where self.os_receiver .try_recv()? .to() - .map_err(IpcError::Bincode) + .map_err(IpcError::SerializationError) .map_err(TryRecvError::IpcError) } @@ -269,7 +222,7 @@ where self.os_receiver .try_recv_timeout(duration)? .to() - .map_err(IpcError::Bincode) + .map_err(IpcError::SerializationError) .map_err(TryRecvError::IpcError) } @@ -363,12 +316,12 @@ where } /// Send data across the channel to the receiver. - pub fn send(&self, data: T) -> Result<(), bincode::Error> { + pub fn send(&self, data: T) -> Result<(), IpcError> { let mut bytes = Vec::with_capacity(4096); OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| { OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION.with( |os_ipc_shared_memory_regions_for_serialization| { - bincode::serialize_into(&mut bytes, &data)?; + bincode::serialize_into(&mut bytes, &data).map_err(SerializationError)?; let os_ipc_channels = os_ipc_channels_for_serialization.take(); let os_ipc_shared_memory_regions = os_ipc_shared_memory_regions_for_serialization.take(); @@ -710,7 +663,7 @@ impl IpcMessage { } /// Deserialize the raw data in the contained message into the inferred type. - pub fn to(self) -> Result + pub fn to(self) -> Result where T: for<'de> Deserialize<'de> + Serialize, { @@ -725,7 +678,7 @@ impl IpcMessage { .map(Some) .collect(); - let result = bincode::deserialize(&self.data[..]); + let result = bincode::deserialize(&self.data[..]).map_err(|e| e.into()); // Clear the shared memory let _ = os_ipc_shared_memory_regions_for_deserialization.take(); @@ -866,7 +819,7 @@ where )) } - pub fn accept(self) -> Result<(IpcReceiver, T), bincode::Error> { + pub fn accept(self) -> Result<(IpcReceiver, T), IpcError> { let (os_receiver, ipc_message) = self.os_server.accept()?; Ok(( IpcReceiver { diff --git a/src/lib.rs b/src/lib.rs index cbdb2c63..7836e795 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ pub mod asynch; #[cfg(all(not(feature = "force-inprocess"), target_os = "windows"))] extern crate windows; +mod error; pub mod ipc; pub mod platform; pub mod router; @@ -39,6 +40,6 @@ pub mod router; #[cfg(test)] mod test; -pub use bincode::{Error, ErrorKind}; +pub use error::{IpcError, TryRecvError}; #[cfg(all(not(feature = "force-inprocess"), target_os = "macos"))] pub use platform::set_bootstrap_prefix; diff --git a/src/platform/inprocess/mod.rs b/src/platform/inprocess/mod.rs index ce5206ba..53b06c6f 100644 --- a/src/platform/inprocess/mod.rs +++ b/src/platform/inprocess/mod.rs @@ -7,19 +7,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::ipc::{self, IpcMessage}; -use bincode; +use crate::ipc::IpcMessage; use crossbeam_channel::{self, Receiver, RecvTimeoutError, Select, Sender, TryRecvError}; use std::cell::{Ref, RefCell}; use std::cmp::PartialEq; use std::collections::hash_map::HashMap; -use std::error::Error as StdError; use std::fmt::{self, Debug, Formatter}; use std::io; use std::ops::{Deref, RangeFrom}; use std::slice; use std::sync::{Arc, LazyLock, Mutex}; use std::time::Duration; +use std::usize; use uuid::Uuid; #[derive(Clone)] @@ -371,11 +370,15 @@ impl OsIpcSharedMemory { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Error)] pub enum ChannelError { + #[error("Channel Closed")] ChannelClosedError, + #[error("Broken Pipe")] BrokenPipeError, + #[error("Channel Empty")] ChannelEmpty, + #[error("Unknown Error")] UnknownError, } @@ -386,42 +389,23 @@ impl ChannelError { } } -impl fmt::Display for ChannelError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - ChannelError::ChannelClosedError => write!(fmt, "channel closed"), - ChannelError::BrokenPipeError => write!(fmt, "broken pipe"), - ChannelError::ChannelEmpty => write!(fmt, "channel empty"), - ChannelError::UnknownError => write!(fmt, "unknown error"), - } - } -} - -impl StdError for ChannelError {} - -impl From for bincode::Error { - fn from(crossbeam_error: ChannelError) -> Self { - io::Error::from(crossbeam_error).into() - } -} - -impl From for ipc::IpcError { +impl From for crate::IpcError { fn from(error: ChannelError) -> Self { match error { - ChannelError::ChannelClosedError => ipc::IpcError::Disconnected, - e => ipc::IpcError::Bincode(io::Error::from(e).into()), + ChannelError::ChannelClosedError => crate::IpcError::Disconnected, + e => crate::IpcError::Io(io::Error::from(e).into()), } } } -impl From for ipc::TryRecvError { +impl From for crate::TryRecvError { fn from(error: ChannelError) -> Self { match error { ChannelError::ChannelClosedError => { - ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected) + crate::TryRecvError::IpcError(crate::IpcError::Disconnected) }, - ChannelError::ChannelEmpty => ipc::TryRecvError::Empty, - e => ipc::TryRecvError::IpcError(ipc::IpcError::Bincode(io::Error::from(e).into())), + ChannelError::ChannelEmpty => crate::TryRecvError::Empty, + e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e).into())), } } } diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index ac6d23bf..fbbae772 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -12,14 +12,12 @@ use self::mach_sys::{kern_return_t, mach_msg_body_t, mach_msg_header_t, mach_msg use self::mach_sys::{mach_msg_ool_descriptor_t, mach_msg_port_descriptor_t, mach_msg_type_name_t}; use self::mach_sys::{mach_msg_timeout_t, mach_port_limits_t, mach_port_msgcount_t}; use self::mach_sys::{mach_port_right_t, mach_port_t, mach_task_self_, vm_inherit_t}; -use crate::ipc::{self, IpcMessage}; +use crate::ipc::IpcMessage; -use bincode; use libc::{self, c_char, c_uint, c_void, size_t}; use rand::{self, Rng}; use std::cell::Cell; use std::convert::TryInto; -use std::error::Error as StdError; use std::ffi::CString; use std::fmt::{self, Debug, Formatter}; use std::io; @@ -29,6 +27,7 @@ use std::ptr; use std::slice; use std::sync::{OnceLock, RwLock}; use std::time::Duration; +use thiserror::Error; mod mach_sys; @@ -1001,43 +1000,28 @@ impl Message { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, Error, PartialEq)] pub enum KernelError { + #[error("Success")] Success, + #[error("No room in IPC name space for another right.")] NoSpace, + #[error("Name doesn't denote a right in the task")] InvalidName, + #[error("Name denotes a right, but not an appropiate right.")] InvalidRight, + #[error("Blatant range error")] InvalidValue, + #[error("The supplied (port) capability is improper")] InvalidCapability, + #[error("Operation would overflow limit on user-references")] UrefsOverflow, + #[error("Receive right is not a member of a port set.")] NotInSet, + #[error("Unkown kernel error. {0}")] Unknown(kern_return_t), } -impl fmt::Display for KernelError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - KernelError::Success => write!(fmt, "Success."), - KernelError::NoSpace => write!(fmt, "No room in IPC name space for another right."), - KernelError::InvalidName => write!(fmt, "Name doesn't denote a right in the task."), - KernelError::InvalidRight => { - write!(fmt, "Name denotes a right, but not an appropriate right.") - }, - KernelError::InvalidValue => write!(fmt, "Blatant range error."), - KernelError::InvalidCapability => { - write!(fmt, "The supplied (port) capability is improper.") - }, - KernelError::UrefsOverflow => { - write!(fmt, "Operation would overflow limit on user-references.") - }, - KernelError::NotInSet => write!(fmt, "Receive right is not a member of a port set."), - KernelError::Unknown(code) => write!(fmt, "Unknown kernel error: {:x}", code), - } - } -} - -impl StdError for KernelError {} - impl From for KernelError { fn from(code: kern_return_t) -> KernelError { match code { @@ -1054,10 +1038,10 @@ impl From for KernelError { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, Error, PartialEq)] pub enum MachError { Success, - Kernel(KernelError), + Kernel(#[from] KernelError), IpcSpace, VmSpace, IpcKernel, @@ -1189,14 +1173,6 @@ impl fmt::Display for MachError { } } -impl StdError for MachError {} - -impl From for bincode::Error { - fn from(mach_error: MachError) -> Self { - io::Error::from(mach_error).into() - } -} - impl From for MachError { fn from(code: mach_msg_return_t) -> MachError { match code { @@ -1244,27 +1220,23 @@ impl From for MachError { } } -impl From for MachError { - fn from(kernel_error: KernelError) -> MachError { - MachError::Kernel(kernel_error) - } -} - -impl From for ipc::TryRecvError { +impl From for crate::TryRecvError { fn from(error: MachError) -> Self { match error { - MachError::NotifyNoSenders => ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected), - MachError::RcvTimedOut => ipc::TryRecvError::Empty, - e => ipc::TryRecvError::IpcError(ipc::IpcError::Io(io::Error::from(e))), + MachError::NotifyNoSenders => { + crate::TryRecvError::IpcError(crate::IpcError::Disconnected) + }, + MachError::RcvTimedOut => crate::TryRecvError::Empty, + e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e))), } } } -impl From for ipc::IpcError { +impl From for crate::IpcError { fn from(error: MachError) -> Self { match error { - MachError::NotifyNoSenders => ipc::IpcError::Disconnected, - e => ipc::IpcError::Io(io::Error::from(e)), + MachError::NotifyNoSenders => crate::IpcError::Disconnected, + e => crate::IpcError::Io(io::Error::from(e)), } } } diff --git a/src/platform/unix/mod.rs b/src/platform/unix/mod.rs index 69a9b086..3feba058 100644 --- a/src/platform/unix/mod.rs +++ b/src/platform/unix/mod.rs @@ -8,7 +8,7 @@ // except according to those terms. use crate::ipc::{self, IpcMessage}; -use bincode; +use crate::ipc::IpcMessage; use libc::{ self, cmsghdr, linger, CMSG_DATA, CMSG_LEN, CMSG_SPACE, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, SOCK_SEQPACKET, SOL_SOCKET, @@ -24,7 +24,6 @@ use std::cell::Cell; use std::cmp; use std::collections::HashMap; use std::convert::TryInto; -use std::error::Error as StdError; use std::ffi::{c_uint, CString}; use std::fmt::{self, Debug, Formatter}; use std::hash::BuildHasherDefault; @@ -39,6 +38,7 @@ use std::sync::{Arc, LazyLock}; use std::thread; use std::time::{Duration, UNIX_EPOCH}; use tempfile::{Builder, TempDir}; +use thiserror::Error; const MAX_FDS_IN_CMSG: u32 = 64; @@ -59,11 +59,11 @@ const RECVMSG_FLAGS: c_int = 0; #[cfg(target_env = "gnu")] type IovLen = usize; -#[cfg(target_env = "gnu")] -type MsgControlLen = size_t; #[cfg(not(target_env = "gnu"))] type IovLen = i32; +#[cfg(target_env = "gnu")] +type MsgControlLen = size_t; #[cfg(not(target_env = "gnu"))] type MsgControlLen = socklen_t; @@ -899,7 +899,7 @@ impl OsIpcSharedMemory { } } -#[derive(Debug)] +#[derive(Debug, Error)] pub enum UnixError { Errno(c_int), ChannelClosed, @@ -917,6 +917,15 @@ impl UnixError { } } +impl From for crate::IpcError { + fn from(error: UnixError) -> Self { + match error { + UnixError::ChannelClosed => crate::IpcError::Disconnected, + e => crate::IpcError::Io(io::Error::from(e)), + } + } +} + impl fmt::Display for UnixError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match self { @@ -929,14 +938,6 @@ impl fmt::Display for UnixError { } } -impl StdError for UnixError {} - -impl From for bincode::Error { - fn from(unix_error: UnixError) -> Self { - io::Error::from(unix_error).into() - } -} - impl From for io::Error { fn from(unix_error: UnixError) -> io::Error { match unix_error { @@ -947,23 +948,16 @@ impl From for io::Error { } } -impl From for ipc::IpcError { +impl From for crate::TryRecvError { fn from(error: UnixError) -> Self { match error { - UnixError::ChannelClosed => ipc::IpcError::Disconnected, - e => ipc::IpcError::Io(io::Error::from(e)), - } - } -} - -impl From for ipc::TryRecvError { - fn from(error: UnixError) -> Self { - match error { - UnixError::ChannelClosed => ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected), + UnixError::ChannelClosed => { + crate::TryRecvError::IpcError(crate::IpcError::Disconnected) + }, UnixError::Errno(code) if code == EAGAIN || code == EWOULDBLOCK => { - ipc::TryRecvError::Empty + crate::TryRecvError::Empty }, - e => ipc::TryRecvError::IpcError(ipc::IpcError::Io(io::Error::from(e))), + e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e))), } } } diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index 2deb8215..b4ca827c 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -7,9 +7,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::ipc::{self, IpcMessage}; +use crate::ipc::IpcMessage; use bincode; use serde_core; +use thiserror::Error; use std::{ cell::RefCell, @@ -1948,10 +1949,13 @@ impl OsOpaqueIpcChannel { } } -#[derive(Debug)] +#[derive(Debug, Error)] pub enum WinIpcError { - WinError(WinError), + #[error("Windows Error {0}")] + WinError(#[from] WinError), + #[error("Channel Closed")] ChannelClosed, + #[error("No Data")] NoData, } @@ -1961,33 +1965,23 @@ impl WinIpcError { } } -impl From for bincode::Error { - fn from(error: WinIpcError) -> bincode::Error { - io::Error::from(error).into() - } -} - -impl From for WinIpcError { - fn from(e: WinError) -> Self { - Self::WinError(e) - } -} - -impl From for ipc::IpcError { +impl From for crate::IpcError { fn from(error: WinIpcError) -> Self { match error { - WinIpcError::ChannelClosed => ipc::IpcError::Disconnected, - e => ipc::IpcError::Io(io::Error::from(e)), + WinIpcError::ChannelClosed => crate::IpcError::Disconnected, + e => crate::IpcError::Io(io::Error::from(e)), } } } -impl From for ipc::TryRecvError { +impl From for crate::TryRecvError { fn from(error: WinIpcError) -> Self { match error { - WinIpcError::ChannelClosed => ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected), - WinIpcError::NoData => ipc::TryRecvError::Empty, - e => ipc::TryRecvError::IpcError(ipc::IpcError::Io(io::Error::from(e))), + WinIpcError::ChannelClosed => { + crate::TryRecvError::IpcError(crate::IpcError::Disconnected) + }, + WinIpcError::NoData => crate::TryRecvError::Empty, + e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e))), } } } diff --git a/src/router.rs b/src/router.rs index ac96678b..e009208c 100644 --- a/src/router.rs +++ b/src/router.rs @@ -17,13 +17,12 @@ use std::collections::HashMap; use std::sync::{LazyLock, Mutex}; use std::thread::{self, JoinHandle}; +use crate::error::SerializationError; +use crate::ipc::OpaqueIpcReceiver; +use crate::ipc::{self, IpcMessage, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender}; use crossbeam_channel::{self, Receiver, Sender}; use serde_core::{Deserialize, Serialize}; -use crate::ipc::{ - self, IpcMessage, IpcReceiver, IpcReceiverSet, IpcSelectionResult, IpcSender, OpaqueIpcReceiver, -}; - /// Global object wrapping a `RouterProxy`. /// Add routes ([add_route](RouterProxy::add_route)), or convert IpcReceiver /// to crossbeam channels (e.g. [route_ipc_receiver_to_new_crossbeam_receiver](RouterProxy::route_ipc_receiver_to_new_crossbeam_receiver)) @@ -295,7 +294,7 @@ enum RouterHandler { } /// Like [RouterMultiHandler] but includes the type that will be passed to the callback -pub type TypedRouterMultiHandler = Box) + Send>; +pub type TypedRouterMultiHandler = Box) + Send>; /// Like [RouterOneShotHandler] but includes the type that will be passed to the callback -pub type TypedRouterOneShotHandler = Box) + Send>; +pub type TypedRouterOneShotHandler = Box) + Send>; diff --git a/src/test.rs b/src/test.rs index 3cefecd3..c44bda08 100644 --- a/src/test.rs +++ b/src/test.rs @@ -129,7 +129,7 @@ fn simple() { assert_eq!(person, received_person); drop(tx); match rx.recv().unwrap_err() { - ipc::IpcError::Disconnected => (), + crate::IpcError::Disconnected => (), e => panic!("expected disconnected error, got {e:?}"), } } @@ -576,19 +576,19 @@ fn try_recv() { let person = ("Patrick Walton".to_owned(), 29); let (tx, rx) = ipc::channel().unwrap(); match rx.try_recv() { - Err(ipc::TryRecvError::Empty) => (), + Err(crate::TryRecvError::Empty) => (), v => panic!("Expected empty channel err: {v:?}"), } tx.send(person.clone()).unwrap(); let received_person = rx.try_recv().unwrap(); assert_eq!(person, received_person); match rx.try_recv() { - Err(ipc::TryRecvError::Empty) => (), + Err(crate::TryRecvError::Empty) => (), v => panic!("Expected empty channel err: {v:?}"), } drop(tx); match rx.try_recv() { - Err(ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected)) => (), + Err(crate::TryRecvError::IpcError(crate::IpcError::Disconnected)) => (), v => panic!("Expected disconnected err: {v:?}"), } } @@ -600,7 +600,7 @@ fn try_recv_timeout() { let timeout = Duration::from_millis(1000); let start_recv = Instant::now(); match rx.try_recv_timeout(timeout) { - Err(ipc::TryRecvError::Empty) => { + Err(crate::TryRecvError::Empty) => { assert!(start_recv.elapsed() >= Duration::from_millis(500)) }, v => panic!("Expected empty channel err: {v:?}"), @@ -612,14 +612,14 @@ fn try_recv_timeout() { assert_eq!(person, received_person); let start_recv = Instant::now(); match rx.try_recv_timeout(timeout) { - Err(ipc::TryRecvError::Empty) => { + Err(crate::TryRecvError::Empty) => { assert!(start_recv.elapsed() >= Duration::from_millis(500)) }, v => panic!("Expected empty channel err: {v:?}"), } drop(tx); match rx.try_recv_timeout(timeout) { - Err(ipc::TryRecvError::IpcError(ipc::IpcError::Disconnected)) => (), + Err(crate::TryRecvError::IpcError(crate::IpcError::Disconnected)) => (), v => panic!("Expected disconnected err: {v:?}"), } } From 822d9330ff2daebe85b4433428d1a45c9284138d Mon Sep 17 00:00:00 2001 From: Narfinger Date: Wed, 17 Dec 2025 11:20:40 +0100 Subject: [PATCH 2/6] fix tests Signed-off-by: Narfinger --- src/platform/inprocess/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/inprocess/mod.rs b/src/platform/inprocess/mod.rs index 53b06c6f..663ecead 100644 --- a/src/platform/inprocess/mod.rs +++ b/src/platform/inprocess/mod.rs @@ -19,6 +19,7 @@ use std::slice; use std::sync::{Arc, LazyLock, Mutex}; use std::time::Duration; use std::usize; +use thiserror::Error; use uuid::Uuid; #[derive(Clone)] From 5876dfc1ea5b577569a141b817db6877e992ba07 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Wed, 17 Dec 2025 11:28:22 +0100 Subject: [PATCH 3/6] fix clippy lints Signed-off-by: Narfinger --- src/platform/inprocess/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/platform/inprocess/mod.rs b/src/platform/inprocess/mod.rs index 663ecead..ce622a97 100644 --- a/src/platform/inprocess/mod.rs +++ b/src/platform/inprocess/mod.rs @@ -18,7 +18,6 @@ use std::ops::{Deref, RangeFrom}; use std::slice; use std::sync::{Arc, LazyLock, Mutex}; use std::time::Duration; -use std::usize; use thiserror::Error; use uuid::Uuid; @@ -394,7 +393,7 @@ impl From for crate::IpcError { fn from(error: ChannelError) -> Self { match error { ChannelError::ChannelClosedError => crate::IpcError::Disconnected, - e => crate::IpcError::Io(io::Error::from(e).into()), + e => crate::IpcError::Io(io::Error::from(e)), } } } @@ -406,7 +405,7 @@ impl From for crate::TryRecvError { crate::TryRecvError::IpcError(crate::IpcError::Disconnected) }, ChannelError::ChannelEmpty => crate::TryRecvError::Empty, - e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e).into())), + e => crate::TryRecvError::IpcError(crate::IpcError::Io(io::Error::from(e))), } } } From 89a598d53c29b3220f8662453b902a74afef6e5d Mon Sep 17 00:00:00 2001 From: Narfinger Date: Mon, 5 Jan 2026 11:28:09 +0100 Subject: [PATCH 4/6] formatting Signed-off-by: Narfinger --- src/platform/unix/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/unix/mod.rs b/src/platform/unix/mod.rs index 3feba058..f1bd1a25 100644 --- a/src/platform/unix/mod.rs +++ b/src/platform/unix/mod.rs @@ -7,8 +7,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::ipc::{self, IpcMessage}; use crate::ipc::IpcMessage; +use crate::ipc::{self, IpcMessage}; use libc::{ self, cmsghdr, linger, CMSG_DATA, CMSG_LEN, CMSG_SPACE, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, SOCK_SEQPACKET, SOL_SOCKET, From 447902b46f1a3d8e7e5696babd5f7a45291890a7 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Mon, 5 Jan 2026 11:29:35 +0100 Subject: [PATCH 5/6] formatting Signed-off-by: Narfinger --- src/platform/unix/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/unix/mod.rs b/src/platform/unix/mod.rs index f1bd1a25..18c2d3b9 100644 --- a/src/platform/unix/mod.rs +++ b/src/platform/unix/mod.rs @@ -7,7 +7,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::ipc::IpcMessage; use crate::ipc::{self, IpcMessage}; use libc::{ self, cmsghdr, linger, CMSG_DATA, CMSG_LEN, CMSG_SPACE, MAP_FAILED, MAP_SHARED, PROT_READ, From b035ab507deabb29508adc796f1dbf93e752efa7 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Mon, 5 Jan 2026 11:36:54 +0100 Subject: [PATCH 6/6] formatting Signed-off-by: Narfinger --- src/platform/unix/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/unix/mod.rs b/src/platform/unix/mod.rs index 18c2d3b9..1fc684ea 100644 --- a/src/platform/unix/mod.rs +++ b/src/platform/unix/mod.rs @@ -7,7 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::ipc::{self, IpcMessage}; +use crate::ipc::IpcMessage; use libc::{ self, cmsghdr, linger, CMSG_DATA, CMSG_LEN, CMSG_SPACE, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, SOCK_SEQPACKET, SOL_SOCKET,