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
19pub type BasicProperties = basic::AMQPProperties;
21
22#[derive(Clone, Debug, PartialEq)]
24pub struct AMQPError {
25 kind: AMQPErrorKind,
26 message: ShortString,
27}
28
29impl AMQPError {
30 pub fn new(kind: AMQPErrorKind, message: ShortString) -> Self {
32 Self { kind, message }
33 }
34
35 pub fn from_id(id: Identifier, message: ShortString) -> Option<Self> {
37 AMQPErrorKind::from_id(id).map(|kind| Self { kind, message })
38 }
39
40 pub fn kind(&self) -> &AMQPErrorKind {
42 &self.kind
43 }
44
45 pub fn get_id(&self) -> Identifier {
47 self.kind.get_id()
48 }
49
50 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#[derive(Clone, Debug, PartialEq)]
84pub enum AMQPErrorKind {
85 Soft(AMQPSoftError),
87 Hard(AMQPHardError),
89}
90
91impl AMQPErrorKind {
92 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 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 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}