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