use std::io;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, IpcError>;
#[derive(Error, Debug)]
pub enum IpcError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("Channel closed")]
Closed,
#[error("Invalid name: {0}")]
InvalidName(String),
#[error("Resource already exists: {0}")]
AlreadyExists(String),
#[error("Resource not found: {0}")]
NotFound(String),
#[error("Permission denied: {0}")]
PermissionDenied(String),
#[error("Operation timed out")]
Timeout,
#[error("Buffer too small: need {needed}, got {got}")]
BufferTooSmall { needed: usize, got: usize },
#[error("Serialization error: {0}")]
Serialization(String),
#[error("Deserialization error: {0}")]
Deserialization(String),
#[error("Platform error: {0}")]
Platform(String),
#[error("Invalid state: {0}")]
InvalidState(String),
#[error("Operation would block")]
WouldBlock,
#[error("{0}")]
Other(String),
}
impl IpcError {
pub fn io(err: io::Error) -> Self {
Self::Io(err)
}
pub fn serialization(msg: impl Into<String>) -> Self {
Self::Serialization(msg.into())
}
pub fn deserialization(msg: impl Into<String>) -> Self {
Self::Deserialization(msg.into())
}
pub fn is_would_block(&self) -> bool {
matches!(self, Self::WouldBlock)
|| matches!(self, Self::Io(e) if e.kind() == io::ErrorKind::WouldBlock)
}
pub fn is_timeout(&self) -> bool {
matches!(self, Self::Timeout)
|| matches!(self, Self::Io(e) if e.kind() == io::ErrorKind::TimedOut)
}
}
#[cfg(feature = "python-bindings")]
impl From<IpcError> for pyo3::PyErr {
fn from(err: IpcError) -> pyo3::PyErr {
use pyo3::exceptions::*;
match err {
IpcError::Io(e) => PyIOError::new_err(e.to_string()),
IpcError::Closed => PyConnectionError::new_err("Channel closed"),
IpcError::InvalidName(s) => PyValueError::new_err(s),
IpcError::AlreadyExists(s) => PyFileExistsError::new_err(s),
IpcError::NotFound(s) => PyFileNotFoundError::new_err(s),
IpcError::PermissionDenied(s) => PyPermissionError::new_err(s),
IpcError::Timeout => PyTimeoutError::new_err("Operation timed out"),
IpcError::BufferTooSmall { needed, got } => {
PyBufferError::new_err(format!("Buffer too small: need {needed}, got {got}"))
}
IpcError::Serialization(s) => PyValueError::new_err(s),
IpcError::Deserialization(s) => PyValueError::new_err(s),
IpcError::Platform(s) => PyOSError::new_err(s),
IpcError::InvalidState(s) => PyRuntimeError::new_err(s),
IpcError::WouldBlock => PyBlockingIOError::new_err("Operation would block"),
IpcError::Other(s) => PyRuntimeError::new_err(s),
}
}
}