Skip to main content

asteroid_mq_model/edge/
connection.rs

1use futures_util::{Sink, Stream};
2use std::borrow::Cow;
3
4use crate::codec::CodecError;
5
6use super::EdgePayload;
7
8#[derive(Debug)]
9pub struct EdgeConnectionError {
10    pub kind: EdgeConnectionErrorKind,
11    pub context: Cow<'static, str>,
12}
13
14impl std::fmt::Display for EdgeConnectionError {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        write!(f, "{}: {}", self.context, self.kind)
17    }
18}
19
20impl EdgeConnectionError {
21    pub fn new(kind: EdgeConnectionErrorKind, context: impl Into<Cow<'static, str>>) -> Self {
22        Self {
23            kind,
24            context: context.into(),
25        }
26    }
27    pub const fn underlying<E: std::error::Error + Send + 'static>(
28        context: impl Into<Cow<'static, str>>,
29    ) -> impl FnOnce(E) -> Self {
30        move |e| Self::new(EdgeConnectionErrorKind::Underlying(Box::new(e)), context)
31    }
32    pub const fn codec(context: impl Into<Cow<'static, str>>) -> impl FnOnce(CodecError) -> Self {
33        move |e| Self::new(EdgeConnectionErrorKind::Codec(e), context)
34    }
35}
36#[derive(Debug)]
37pub enum EdgeConnectionErrorKind {
38    Io(std::io::Error),
39    Underlying(Box<dyn std::error::Error + Send>),
40    Codec(CodecError),
41    Closed,
42    Timeout,
43    Protocol,
44    Existed,
45    Reconnect,
46}
47
48impl std::fmt::Display for EdgeConnectionErrorKind {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            EdgeConnectionErrorKind::Io(e) => write!(f, "io error: {}", e),
52            EdgeConnectionErrorKind::Underlying(e) => write!(f, "underlying error: {}", e),
53            EdgeConnectionErrorKind::Codec(e) => write!(f, "codec error: {}", e),
54            EdgeConnectionErrorKind::Closed => write!(f, "connection closed"),
55            EdgeConnectionErrorKind::Timeout => write!(f, "timeout"),
56            EdgeConnectionErrorKind::Protocol => write!(f, "protocol error"),
57            EdgeConnectionErrorKind::Existed => write!(f, "existed"),
58            EdgeConnectionErrorKind::Reconnect => write!(f, "reconnect"),
59        }
60    }
61}
62
63impl std::error::Error for EdgeConnectionError {
64    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
65        match &self.kind {
66            EdgeConnectionErrorKind::Io(e) => Some(e),
67            EdgeConnectionErrorKind::Underlying(e) => Some(&**e),
68            EdgeConnectionErrorKind::Codec(e) => Some(e),
69            _ => None,
70        }
71    }
72
73    fn description(&self) -> &str {
74        match &self.kind {
75            EdgeConnectionErrorKind::Io(_) => "io error",
76            EdgeConnectionErrorKind::Underlying(_) => "underlying error",
77            EdgeConnectionErrorKind::Codec(_) => "codec error",
78            EdgeConnectionErrorKind::Closed => "connection closed",
79            EdgeConnectionErrorKind::Timeout => "timeout",
80            EdgeConnectionErrorKind::Protocol => "protocol error",
81            EdgeConnectionErrorKind::Existed => "existed",
82            EdgeConnectionErrorKind::Reconnect => "reconnect",
83        }
84    }
85}
86
87pub trait EdgeNodeConnection:
88    Send
89    + 'static
90    + Stream<Item = Result<EdgePayload, EdgeConnectionError>>
91    + Sink<EdgePayload, Error = EdgeConnectionError>
92{
93}