use std::sync::PoisonError;
use crate::{
no_key::wrappers::NoKeyWrapper,
serialization::{cdr_deserializer, cdr_serializer},
TopicKind,
};
#[cfg(feature = "security")]
use crate::security::SecurityError;
#[derive(Debug, thiserror::Error)]
pub enum ReadError {
#[error("Deserialization error: {reason}")]
Deserialization { reason: String },
#[error("Received dispose message with unknown key: {details}")]
UnknownKey { details: String },
#[error(
"Synchronization failed due poisoning. Another thread may have panicked. Details: {reason}"
)]
Poisoned { reason: String },
#[error("Internal error: {reason}")]
Internal { reason: String },
}
#[doc(hidden)]
#[macro_export]
macro_rules! read_error_deserialization {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( ReadError::Deserialization{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! read_error_unknown_key {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( ReadError::UnknownKey{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! read_error_poisoned {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( ReadError::Poisoned{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! read_error_internal {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( ReadError::Internal{ reason: format!($($arg)*) } )
}
)
}
impl From<cdr_deserializer::Error> for ReadError {
fn from(e: cdr_deserializer::Error) -> Self {
ReadError::Deserialization {
reason: e.to_string(),
}
}
}
pub type ReadResult<T> = std::result::Result<T, ReadError>;
#[derive(Debug, thiserror::Error)]
pub enum WriteError<D> {
#[error("Serialization error: {reason}")]
Serialization { reason: String, data: D },
#[error("Cannot communicate. Background thread may have panicked: {reason}")]
Poisoned { reason: String, data: D },
#[error("std:io:Error {0}")]
Io(#[from] std::io::Error),
#[error("Write operation timed out while blocking")]
WouldBlock { data: D },
#[error("Internal error: {reason}")]
Internal { reason: String },
}
impl<T> From<PoisonError<T>> for WriteError<()> {
fn from(poison_error: PoisonError<T>) -> Self {
Self::Poisoned {
reason: poison_error.to_string(),
data: (),
}
}
}
impl From<cdr_serializer::Error> for WriteError<()> {
fn from(e: cdr_serializer::Error) -> Self {
WriteError::Serialization {
reason: e.to_string(),
data: (),
}
}
}
impl<D> WriteError<D> {
pub fn forget_data(self) -> WriteError<()> {
match self {
WriteError::Serialization { reason, data: _ } => {
WriteError::Serialization { reason, data: () }
}
WriteError::Poisoned { reason, data: _ } => WriteError::Poisoned { reason, data: () },
WriteError::Io(e) => WriteError::Io(e),
WriteError::WouldBlock { data: _ } => WriteError::WouldBlock { data: () },
WriteError::Internal { reason } => WriteError::Internal { reason },
}
}
}
pub type WriteResult<T, D> = std::result::Result<T, WriteError<D>>;
pub(crate) fn unwrap_no_key_write_error<D>(
no_key_write_error: WriteError<NoKeyWrapper<D>>,
) -> WriteError<D> {
match no_key_write_error {
WriteError::Serialization { reason, data } => WriteError::Serialization {
reason,
data: data.d,
},
WriteError::Poisoned { reason, data } => WriteError::Poisoned {
reason,
data: data.d,
},
WriteError::WouldBlock { data } => WriteError::WouldBlock { data: data.d },
WriteError::Internal { reason } => WriteError::Internal { reason },
WriteError::Io(io) => WriteError::Io(io),
}
}
#[derive(Debug, thiserror::Error)]
pub enum CreateError {
#[error("Object creation failed, because necessary resource has been dropped: {reason}")]
ResourceDropped { reason: String },
#[error("Cannot communicate. Background thread may have panicked: {reason}")]
Poisoned { reason: String },
#[error("std:io:Error {0}")]
Io(#[from] std::io::Error),
#[error("Wrong Topic kind. Expected {0}")]
TopicKind(TopicKind),
#[error("Internal error: {reason}")]
Internal { reason: String },
#[error("Invalid call parameter: {reason}")]
BadParameter { reason: String },
#[error("Resource allocation failed: {reason}")]
OutOfResources { reason: String },
#[cfg(feature = "security")]
#[error("Not allowed by security: {reason}")]
NotAllowedBySecurity { reason: String },
}
#[doc(hidden)]
#[macro_export]
macro_rules! create_error_dropped {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::ResourceDropped{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! create_error_poisoned {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::Poisoned{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! create_error_internal {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::Internal{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! create_error_bad_parameter {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::BadParameter{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! create_error_out_of_resources {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::OutOfResources{ reason: format!($($arg)*) } )
}
)
}
#[doc(hidden)]
#[cfg(feature = "security")]
#[macro_export]
macro_rules! create_error_not_allowed_by_security {
($($arg:tt)*) => (
{ log::error!($($arg)*);
Err( CreateError::NotAllowedBySecurity{ reason: format!($($arg)*) } )
}
)
}
impl<T> From<PoisonError<T>> for CreateError {
fn from(poison_error: PoisonError<T>) -> Self {
Self::Poisoned {
reason: poison_error.to_string(),
}
}
}
#[cfg(feature = "security")]
impl From<SecurityError> for CreateError {
fn from(security_error: SecurityError) -> Self {
CreateError::NotAllowedBySecurity {
reason: security_error.to_string(),
}
}
}
pub type CreateResult<T> = std::result::Result<T, CreateError>;
#[derive(Debug, thiserror::Error)]
pub enum WaitError {
#[error("Waiting timed out")]
Timeout,
}
pub type WaitResult<T> = std::result::Result<T, WaitError>;
#[derive(Debug, thiserror::Error)]
pub enum QosError {
#[error("Parameter value or combination of values was bad. Details: {details}")]
BadParameter { details: String },
}