Skip to main content

amq_protocol/frame/
structs.rs

1use crate::{frame::parsing::traits::ParsableInput, protocol::*, types::*};
2use std::fmt;
3
4/// Enum representing an AMQP channel
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub enum AMQPChannel {
7    /// The Global (id 0) AMQP channel used for creating other channels and for heartbeat
8    Global,
9    /// A regular AMQP channel
10    Id(ChannelId),
11}
12
13impl AMQPChannel {
14    /// Get the channel id
15    #[must_use]
16    pub fn get_id(self) -> ChannelId {
17        match self {
18            AMQPChannel::Global => 0,
19            AMQPChannel::Id(id) => id,
20        }
21    }
22}
23
24impl From<ChannelId> for AMQPChannel {
25    fn from(id: ChannelId) -> AMQPChannel {
26        match id {
27            0 => AMQPChannel::Global,
28            id => AMQPChannel::Id(id),
29        }
30    }
31}
32
33/// The type of AMQP Frame
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum AMQPFrameType {
36    /// The Protocol Header,
37    ProtocolHeader,
38    /// Call a method
39    Method,
40    /// Content header
41    Header,
42    /// Content body
43    Body,
44    /// Heartbeat frame
45    Heartbeat,
46}
47
48/// The different possible frames
49#[derive(Clone, Debug, PartialEq)]
50pub enum AMQPFrame {
51    /// Protocol header frame
52    ProtocolHeader(ProtocolVersion),
53    /// Method call
54    Method(ChannelId, AMQPClass),
55    /// Content header
56    Header(ChannelId, AMQPContentHeader),
57    /// Content body
58    Body(ChannelId, Vec<u8>),
59    /// Heartbeat frame (Channel 0 enforced as per specifications)
60    Heartbeat,
61    /// Invalid Heartbeat frame (With configurable ChannelId, not following specifications)
62    InvalidHeartbeat(ChannelId),
63}
64
65impl AMQPFrame {
66    /// Return whether this frame is an AMQPFrame::Header or not
67    #[must_use]
68    pub fn is_header(&self) -> bool {
69        matches!(self, AMQPFrame::Header(..))
70    }
71
72    /// Returns the channel id associated with this frame
73    #[must_use]
74    pub fn channel_id(&self) -> ChannelId {
75        match self {
76            AMQPFrame::ProtocolHeader(_) => 0,
77            AMQPFrame::Method(id, _) => *id,
78            AMQPFrame::Header(id, _) => *id,
79            AMQPFrame::Body(id, _) => *id,
80            AMQPFrame::Heartbeat => 0,
81            AMQPFrame::InvalidHeartbeat(id) => *id,
82        }
83    }
84}
85
86impl fmt::Display for AMQPFrame {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        match self {
89            AMQPFrame::ProtocolHeader(version) => {
90                f.write_fmt(format_args!("AMQPFrame::ProtocolHeader({version})"))
91            }
92            AMQPFrame::Method(_, klass) => {
93                f.write_fmt(format_args!("AMQPFrame::Method({klass:?})"))
94            }
95            AMQPFrame::Header(..) => f.write_str("AMQPFrame::Header"),
96            AMQPFrame::Body(..) => f.write_str("AMQPFrame::Body"),
97            AMQPFrame::Heartbeat => f.write_str("AMQPFrame::Heartbeat"),
98            AMQPFrame::InvalidHeartbeat(id) => {
99                f.write_fmt(format_args!("AMQPFrame::InvalidHeartbeat({id})"))
100            }
101        }
102    }
103}
104
105/// Protocol version used
106#[derive(Clone, Copy, Debug, PartialEq, Eq)]
107pub struct ProtocolVersion {
108    /// Major version of the protocol
109    pub major: ShortShortUInt,
110    /// Minor version of the protocol
111    pub minor: ShortShortUInt,
112    /// Revision of the protocol
113    pub revision: ShortShortUInt,
114}
115
116impl ProtocolVersion {
117    /// AMQP 0.9.1
118    #[must_use]
119    pub fn amqp_0_9_1() -> Self {
120        Self {
121            major: metadata::MAJOR_VERSION,
122            minor: metadata::MINOR_VERSION,
123            revision: metadata::REVISION,
124        }
125    }
126}
127
128impl fmt::Display for ProtocolVersion {
129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130        f.write_fmt(format_args!(
131            "{}.{}.{}",
132            self.major, self.minor, self.revision
133        ))
134    }
135}
136
137/// Raw AMQP Frame
138#[derive(Clone, Copy, Debug, PartialEq, Eq)]
139pub struct AMQPRawFrame<I: ParsableInput> {
140    /// The type of frame
141    pub frame_type: AMQPFrameType,
142    /// The id this frame was received on
143    pub channel_id: ChannelId,
144    /// The payload of the frame
145    pub payload: I,
146}
147
148/// Content header
149#[derive(Clone, Debug, PartialEq)]
150pub struct AMQPContentHeader {
151    /// The class of content
152    pub class_id: Identifier,
153    /// The size of the content's body
154    pub body_size: PayloadSize,
155    /// The AMQP properties associated with the content
156    pub properties: basic::AMQPProperties,
157}