Skip to main content

amq_protocol_codegen/
specs.rs

1use crate::internal::*;
2
3use amq_protocol_types::*;
4use serde::{Deserialize, Serialize};
5use serde_json::{Value, from_str};
6
7use std::collections::BTreeMap;
8
9/// Structure holding the definition of the protocol
10#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
11pub struct AMQProtocolDefinition {
12    /// The name of the protocol
13    pub name: String,
14    /// The major protocol version
15    pub major_version: ShortShortUInt,
16    /// The minor protocol version
17    pub minor_version: ShortShortUInt,
18    /// The revision of the protocol version
19    pub revision: ShortShortUInt,
20    /// The default port of the protocol
21    pub port: LongUInt,
22    /// The copyright holder of the protocol specification
23    pub copyright: String,
24    /// The domains defined by the protocol specification
25    pub domains: BTreeMap<String, AMQPType>,
26    /// The constants defined by the protocol specification
27    pub constants: Vec<AMQPConstant>,
28    /// The soft errors defined by the protocol specification
29    pub soft_errors: Vec<AMQPConstant>,
30    /// The hard errors defined by the protocol specification
31    pub hard_errors: Vec<AMQPConstant>,
32    /// The classes defined by the protocol specification
33    pub classes: Vec<AMQPClass>,
34    /// Global metadata useful for codegen
35    pub metadata: Value,
36}
37
38impl AMQProtocolDefinition {
39    /// Load protocol definition from reference specification
40    pub fn load(metadata: Option<Value>) -> AMQProtocolDefinition {
41        let specs = include_str!(concat!(
42            env!("CARGO_MANIFEST_DIR"),
43            "/specs/amqp-rabbitmq-0.9.1.json"
44        ));
45
46        from_str::<_AMQProtocolDefinition>(specs)
47            .expect("Failed to parse AMQP specs file")
48            .into_specs(&metadata.unwrap_or_default())
49    }
50}
51
52/// A constant as defined in the AMQP specification
53#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
54pub struct AMQPConstant {
55    /// The name of the constant
56    pub name: String,
57    /// The value of the constant
58    pub value: LongUInt,
59    /// The type of the constant
60    #[serde(rename = "type")]
61    pub amqp_type: AMQPType,
62}
63
64/// A class as defined in the AMQP specification
65#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
66pub struct AMQPClass {
67    /// The id of the class
68    pub id: Identifier,
69    /// The methods of the class
70    pub methods: Vec<AMQPMethod>,
71    /// The name of the class
72    pub name: String,
73    /// The properties of the class
74    pub properties: Vec<AMQPProperty>,
75    /// Extra metadata for code generation
76    pub metadata: Value,
77}
78
79/// A method as defined in the AMQP specification
80#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
81pub struct AMQPMethod {
82    /// The id of the method
83    pub id: Identifier,
84    /// The arguments of the method
85    pub arguments: Vec<AMQPArgument>,
86    /// The name of the method
87    pub name: String,
88    /// Whether this method is synchronous or not
89    pub synchronous: Boolean,
90    /// Whether this method carries some content frames with it
91    pub content: Boolean,
92    /// Extra metadata for code generation
93    pub metadata: Value,
94    /// Whether this method is a reply or not
95    pub is_reply: bool,
96    /// Whether all the arguments have force_default or not
97    pub ignore_args: bool,
98    /// Whether this method can be sent from client to server
99    pub c2s: bool,
100    /// Whether this method can be received from server to client
101    pub s2c: bool,
102}
103
104/// An argument as defined in the AMQP specification
105#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
106pub enum AMQPArgument {
107    /// The argument is holding a value
108    Value(AMQPValueArgument),
109    /// The argument is holding flags
110    Flags(AMQPFlagsArgument),
111}
112
113impl AMQPArgument {
114    pub(crate) fn force_default(&self) -> bool {
115        match self {
116            AMQPArgument::Value(v) => v.force_default,
117            AMQPArgument::Flags(f) => f.force_default(),
118        }
119    }
120}
121
122/// An argument holding a value as defined in the AMQP specification
123#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
124pub struct AMQPValueArgument {
125    /// The type of the argument's value
126    #[serde(rename = "type")]
127    pub amqp_type: AMQPType,
128    /// The name of the argument's value
129    pub name: String,
130    /// The default value of the argument's value
131    pub default_value: Option<AMQPValue>,
132    /// The domain of the argument's value
133    pub domain: Option<String>,
134    /// Whether the default value is forced or not
135    pub force_default: bool,
136}
137
138/// An argument holding a flags as defined in the AMQP specification
139#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
140pub struct AMQPFlagsArgument {
141    /// Whether all the flags have force_default or not
142    pub ignore_flags: bool,
143    /// The actual flags
144    pub flags: Vec<AMQPFlagArgument>,
145}
146
147impl AMQPFlagsArgument {
148    pub(crate) fn force_default(&self) -> bool {
149        self.flags.iter().all(|f| f.force_default)
150    }
151}
152
153/// An argument holding a flag as defined in the AMQP specification
154#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
155pub struct AMQPFlagArgument {
156    /// The name of the flag
157    pub name: String,
158    /// The default value for the flag
159    pub default_value: Boolean,
160    /// Whether the default value is forced or not
161    pub force_default: bool,
162}
163
164/// A property as defined in the AMQP specification
165#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
166pub struct AMQPProperty {
167    /// The type of the property
168    #[serde(rename = "type")]
169    pub amqp_type: AMQPType,
170    /// The name of the property
171    pub name: String,
172}