use crate::types::{
flags::*,
generation::*,
parsing::{traits::ParsableInput, *},
*,
};
use nom::{
combinator::{flat_map, map, map_opt},
error::context,
};
use std::{convert::TryFrom, error, fmt, io::Write};
include!(concat!(env!("OUT_DIR"), "/protocol.rs"));
pub type BasicProperties = basic::AMQPProperties;
#[derive(Clone, Debug, PartialEq)]
pub struct AMQPError {
kind: AMQPErrorKind,
message: ShortString,
}
impl AMQPError {
pub fn new(kind: AMQPErrorKind, message: ShortString) -> Self {
Self { kind, message }
}
pub fn from_id(id: ShortUInt, message: ShortString) -> Option<Self> {
AMQPErrorKind::from_id(id).map(|kind| Self { kind, message })
}
pub fn kind(&self) -> &AMQPErrorKind {
&self.kind
}
pub fn get_id(&self) -> ShortUInt {
self.kind.get_id()
}
pub fn get_message(&self) -> &ShortString {
&self.message
}
}
impl TryFrom<channel::Close> for AMQPError {
type Error = String;
fn try_from(method: channel::Close) -> Result<Self, Self::Error> {
Self::from_id(method.reply_code, method.reply_text.clone())
.ok_or_else(|| format!("Couldn't convert method to error: {:?}", method))
}
}
impl TryFrom<connection::Close> for AMQPError {
type Error = String;
fn try_from(method: connection::Close) -> Result<Self, Self::Error> {
Self::from_id(method.reply_code, method.reply_text.clone())
.ok_or_else(|| format!("Couldn't convert method to error: {:?}", method))
}
}
impl fmt::Display for AMQPError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.kind, self.message)
}
}
impl error::Error for AMQPError {}
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPErrorKind {
Soft(AMQPSoftError),
Hard(AMQPHardError),
}
impl AMQPErrorKind {
pub fn get_id(&self) -> ShortUInt {
match *self {
AMQPErrorKind::Soft(ref s) => s.get_id(),
AMQPErrorKind::Hard(ref h) => h.get_id(),
}
}
pub fn from_id(id: ShortUInt) -> Option<Self> {
AMQPSoftError::from_id(id)
.map(AMQPErrorKind::Soft)
.or_else(|| AMQPHardError::from_id(id).map(AMQPErrorKind::Hard))
}
}
impl fmt::Display for AMQPErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AMQPErrorKind::Soft(err) => write!(f, "AMQP soft error: {}", err),
AMQPErrorKind::Hard(err) => write!(f, "AMQP hard error: {}", err),
}
}
}
impl From<AMQPSoftError> for AMQPErrorKind {
fn from(error: AMQPSoftError) -> Self {
Self::Soft(error)
}
}
impl From<AMQPHardError> for AMQPErrorKind {
fn from(error: AMQPHardError) -> Self {
Self::Hard(error)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_description() {
assert_eq!(
format!(
"{} - {}.{}.{}",
metadata::NAME,
metadata::MAJOR_VERSION,
metadata::MINOR_VERSION,
metadata::REVISION
),
"AMQP - 0.9.1"
);
}
}