1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use crate::{frame::parsing::traits::ParsableInput, protocol::*, types::*};
use std::fmt;

/// Enum representing an AMQP channel
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AMQPChannel {
    /// The Global (id 0) AMQP channel used for creating other channels and for heartbeat
    Global,
    /// A regular AMQP channel
    Id(ShortUInt),
}

impl AMQPChannel {
    /// Get the channel id
    pub fn get_id(self) -> ShortUInt {
        match self {
            AMQPChannel::Global => 0,
            AMQPChannel::Id(id) => id,
        }
    }
}

impl From<ShortUInt> for AMQPChannel {
    fn from(id: ShortUInt) -> AMQPChannel {
        match id {
            0 => AMQPChannel::Global,
            id => AMQPChannel::Id(id),
        }
    }
}

/// The type of AMQP Frame
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AMQPFrameType {
    /// The Protocol Header,
    ProtocolHeader,
    /// Call a method
    Method,
    /// Content header
    Header,
    /// Content body
    Body,
    /// Heartbeat frame
    Heartbeat,
}

/// The different possible frames
#[derive(Clone, Debug, PartialEq)]
pub enum AMQPFrame {
    /// Protocol header frame
    ProtocolHeader(ProtocolVersion),
    /// Method call
    Method(ShortUInt, AMQPClass),
    /// Content header
    Header(ShortUInt, ShortUInt, Box<AMQPContentHeader>),
    /// Content body
    Body(ShortUInt, Vec<u8>),
    /// Heartbeat frame
    Heartbeat(ShortUInt),
}

impl AMQPFrame {
    /// Return whether this frame is an AMQPFrame::Header or not
    pub fn is_header(&self) -> bool {
        if let AMQPFrame::Header(..) = self {
            true
        } else {
            false
        }
    }
}

impl fmt::Display for AMQPFrame {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            AMQPFrame::ProtocolHeader(version) => {
                f.write_fmt(format_args!("AMQPFrame::ProtocolHeader({})", version))
            }
            AMQPFrame::Method(_, klass) => {
                f.write_fmt(format_args!("AMQPFrame::Method({:?})", klass))
            }
            AMQPFrame::Header(..) => f.write_str("AMQPFrame::Header"),
            AMQPFrame::Body(..) => f.write_str("AMQPFrame::Body"),
            AMQPFrame::Heartbeat(_) => f.write_str("AMQPFrame::Heartbeat"),
        }
    }
}

/// Protocol version used
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ProtocolVersion {
    /// Major version of the protocol
    pub major: u8,
    /// Minor version of the protocol
    pub minor: u8,
    /// Revision of the protocol
    pub revision: u8,
}

impl ProtocolVersion {
    /// AMQP 0.9.1
    pub fn amqp_0_9_1() -> Self {
        Self {
            major: metadata::MAJOR_VERSION,
            minor: metadata::MINOR_VERSION,
            revision: metadata::REVISION,
        }
    }
}

impl fmt::Display for ProtocolVersion {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!(
            "{}.{}.{}",
            self.major, self.minor, self.revision
        ))
    }
}

/// Raw AMQP Frame
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AMQPRawFrame<I: ParsableInput> {
    /// The type of frame
    pub frame_type: AMQPFrameType,
    /// The id this frame was received on
    pub channel_id: ShortUInt,
    /// The payload of the frame
    pub payload: I,
}

/// Content header
#[derive(Clone, Debug, PartialEq)]
pub struct AMQPContentHeader {
    /// The class of content
    pub class_id: ShortUInt,
    /// The weight of the content
    pub weight: ShortUInt,
    /// The size of the content's body
    pub body_size: LongLongUInt,
    /// The AMQP properties associated with the content
    pub properties: basic::AMQPProperties,
}