use std::error::Error;
use std::fmt;
use std::time::Duration;
use crate::transport::Connection;
#[derive(Debug, Default, PartialEq)]
pub struct Envelope {
id: String,
payload: Vec<u8>,
}
impl Envelope {
pub fn new(id: String, payload: Vec<u8>) -> Self {
Envelope { id, payload }
}
pub fn id(&self) -> &str {
&self.id
}
pub fn payload(&self) -> &[u8] {
&self.payload
}
pub fn take_payload(self) -> Vec<u8> {
self.payload
}
}
pub trait MatrixLifeCycle: Clone + Send {
fn add(&self, connection: Box<dyn Connection>, id: String) -> Result<usize, MatrixAddError>;
fn remove(&self, id: &str) -> Result<Box<dyn Connection>, MatrixRemoveError>;
}
pub trait MatrixSender: Clone + Send {
fn send(&self, id: String, message: Vec<u8>) -> Result<(), MatrixSendError>;
}
pub trait MatrixReceiver: Clone + Send {
fn recv(&self) -> Result<Envelope, MatrixRecvError>;
fn recv_timeout(&self, timeout: Duration) -> Result<Envelope, MatrixRecvTimeoutError>;
}
#[derive(Debug)]
pub struct MatrixAddError {
pub context: String,
pub source: Option<Box<dyn Error + Send>>,
}
impl MatrixAddError {
pub fn new(context: String, source: Option<Box<dyn Error + Send>>) -> Self {
Self { context, source }
}
}
impl Error for MatrixAddError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Some(ref err) = self.source {
Some(&**err)
} else {
None
}
}
}
impl fmt::Display for MatrixAddError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref err) = self.source {
write!(f, "{}: {}", self.context, err)
} else {
f.write_str(&self.context)
}
}
}
#[derive(Debug)]
pub struct MatrixRemoveError {
pub context: String,
pub source: Option<Box<dyn Error + Send>>,
}
impl MatrixRemoveError {
pub fn new(context: String, source: Option<Box<dyn Error + Send>>) -> Self {
Self { context, source }
}
}
impl Error for MatrixRemoveError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Some(ref err) = self.source {
Some(&**err)
} else {
None
}
}
}
impl fmt::Display for MatrixRemoveError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref err) = self.source {
write!(f, "{}: {}", self.context, err)
} else {
f.write_str(&self.context)
}
}
}
#[derive(Debug)]
pub struct MatrixSendError {
pub context: String,
pub source: Option<Box<dyn Error + Send>>,
}
impl MatrixSendError {
pub fn new(context: String, source: Option<Box<dyn Error + Send>>) -> Self {
Self { context, source }
}
}
impl Error for MatrixSendError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Some(ref err) = self.source {
Some(&**err)
} else {
None
}
}
}
impl fmt::Display for MatrixSendError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref err) = self.source {
write!(f, "{}: {}", self.context, err)
} else {
f.write_str(&self.context)
}
}
}
#[derive(Debug)]
pub enum MatrixRecvError {
Disconnected,
InternalError {
context: String,
source: Option<Box<dyn Error + Send>>,
},
}
impl MatrixRecvError {
pub fn new_internal_error(context: String, source: Option<Box<dyn Error + Send>>) -> Self {
MatrixRecvError::InternalError { context, source }
}
}
impl Error for MatrixRecvError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
MatrixRecvError::Disconnected => None,
MatrixRecvError::InternalError { source, .. } => {
if let Some(ref err) = source {
Some(&**err)
} else {
None
}
}
}
}
}
impl fmt::Display for MatrixRecvError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MatrixRecvError::Disconnected => {
f.write_str("Unable to receive: channel has disconnected")
}
MatrixRecvError::InternalError { context, source } => {
if let Some(ref err) = source {
write!(f, "{}: {}", context, err)
} else {
f.write_str(&context)
}
}
}
}
}
#[derive(Debug)]
pub enum MatrixRecvTimeoutError {
Timeout,
Disconnected,
InternalError {
context: String,
source: Option<Box<dyn Error + Send>>,
},
}
impl MatrixRecvTimeoutError {
pub fn new_internal_error(context: String, source: Option<Box<dyn Error + Send>>) -> Self {
MatrixRecvTimeoutError::InternalError { context, source }
}
}
impl Error for MatrixRecvTimeoutError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
MatrixRecvTimeoutError::Timeout => None,
MatrixRecvTimeoutError::Disconnected => None,
MatrixRecvTimeoutError::InternalError { source, .. } => {
if let Some(ref err) = source {
Some(&**err)
} else {
None
}
}
}
}
}
impl std::fmt::Display for MatrixRecvTimeoutError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MatrixRecvTimeoutError::Timeout => f.write_str("Unable to receive: Timeout"),
MatrixRecvTimeoutError::Disconnected => {
f.write_str("Unable to receive: channel has disconnected")
}
MatrixRecvTimeoutError::InternalError { context, source } => {
if let Some(ref err) = source {
write!(f, "{}: {}", context, err)
} else {
f.write_str(&context)
}
}
}
}
}