amq_protocol/
protocol.rs

1use crate::types::{
2    flags::*,
3    generation::*,
4    parsing::{traits::ParsableInput, *},
5    *,
6};
7use nom::{
8    combinator::{flat_map, map, map_opt},
9    error::context,
10};
11use serde::{Deserialize, Serialize};
12use std::{convert::TryFrom, error, fmt, io::Write};
13
14#[cfg(feature = "codegen")]
15include!(concat!(env!("OUT_DIR"), "/protocol.rs"));
16#[cfg(not(feature = "codegen"))]
17include!("generated.rs");
18
19/// Type alias for AMQP BasicProperties
20pub type BasicProperties = basic::AMQPProperties;
21
22/// An AMQP Error
23#[derive(Clone, Debug, PartialEq)]
24pub struct AMQPError {
25    kind: AMQPErrorKind,
26    message: ShortString,
27}
28
29impl AMQPError {
30    /// Create a new error
31    pub fn new(kind: AMQPErrorKind, message: ShortString) -> Self {
32        Self { kind, message }
33    }
34
35    /// Get the error corresponding to an id
36    pub fn from_id(id: Identifier, message: ShortString) -> Option<Self> {
37        AMQPErrorKind::from_id(id).map(|kind| Self { kind, message })
38    }
39
40    /// Get the kind of error
41    pub fn kind(&self) -> &AMQPErrorKind {
42        &self.kind
43    }
44
45    /// Get the id of the error
46    pub fn get_id(&self) -> Identifier {
47        self.kind.get_id()
48    }
49
50    /// Get the message of the error
51    pub fn get_message(&self) -> &ShortString {
52        &self.message
53    }
54}
55
56impl TryFrom<channel::Close> for AMQPError {
57    type Error = String;
58
59    fn try_from(method: channel::Close) -> Result<Self, Self::Error> {
60        Self::from_id(method.reply_code, method.reply_text.clone())
61            .ok_or_else(|| format!("Couldn't convert method to error: {:?}", method))
62    }
63}
64
65impl TryFrom<connection::Close> for AMQPError {
66    type Error = String;
67
68    fn try_from(method: connection::Close) -> Result<Self, Self::Error> {
69        Self::from_id(method.reply_code, method.reply_text.clone())
70            .ok_or_else(|| format!("Couldn't convert method to error: {:?}", method))
71    }
72}
73
74impl fmt::Display for AMQPError {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        write!(f, "{}: {}", self.kind, self.message)
77    }
78}
79
80impl error::Error for AMQPError {}
81
82/// The kind of AMQP Error
83#[derive(Clone, Debug, PartialEq)]
84pub enum AMQPErrorKind {
85    /// A soft AMQP error
86    Soft(AMQPSoftError),
87    /// A hard AMQP error
88    Hard(AMQPHardError),
89}
90
91impl AMQPErrorKind {
92    /// Get the id of the error
93    pub fn get_id(&self) -> Identifier {
94        match *self {
95            AMQPErrorKind::Soft(ref s) => s.get_id(),
96            AMQPErrorKind::Hard(ref h) => h.get_id(),
97        }
98    }
99
100    /// Get the error kind corresponding to an id
101    pub fn from_id(id: Identifier) -> Option<Self> {
102        AMQPSoftError::from_id(id)
103            .map(AMQPErrorKind::Soft)
104            .or_else(|| AMQPHardError::from_id(id).map(AMQPErrorKind::Hard))
105    }
106}
107
108impl fmt::Display for AMQPErrorKind {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        match self {
111            AMQPErrorKind::Soft(err) => write!(f, "AMQP soft error: {}", err),
112            AMQPErrorKind::Hard(err) => write!(f, "AMQP hard error: {}", err),
113        }
114    }
115}
116
117impl From<AMQPSoftError> for AMQPErrorKind {
118    fn from(error: AMQPSoftError) -> Self {
119        Self::Soft(error)
120    }
121}
122
123impl From<AMQPHardError> for AMQPErrorKind {
124    fn from(error: AMQPHardError) -> Self {
125        Self::Hard(error)
126    }
127}
128
129impl basic::AMQPProperties {
130    #[deprecated(note = "use with_type instead")]
131    /// deprecated: use with_type instead
132    pub fn with_kind(self, value: ShortString) -> Self {
133        self.with_type(value)
134    }
135}
136
137#[cfg(test)]
138mod test {
139    use super::*;
140
141    #[test]
142    fn test_description() {
143        assert_eq!(
144            format!(
145                "{} - {}.{}.{}",
146                metadata::NAME,
147                metadata::MAJOR_VERSION,
148                metadata::MINOR_VERSION,
149                metadata::REVISION
150            ),
151            "AMQP - 0.9.1"
152        );
153    }
154}