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    #[must_use]
41    pub fn load(metadata: Option<Value>) -> AMQProtocolDefinition {
42        let specs = include_str!(concat!(
43            env!("CARGO_MANIFEST_DIR"),
44            "/specs/amqp-rabbitmq-0.9.1.json"
45        ));
46
47        from_str::<_AMQProtocolDefinition>(specs)
48            .expect("Failed to parse AMQP specs file")
49            .into_specs(&metadata.unwrap_or_default())
50    }
51}
52
53/// A constant as defined in the AMQP specification
54#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
55pub struct AMQPConstant {
56    /// The name of the constant
57    pub name: String,
58    /// The value of the constant
59    pub value: LongUInt,
60    /// The type of the constant
61    #[serde(rename = "type")]
62    pub amqp_type: AMQPType,
63}
64
65/// A class as defined in the AMQP specification
66#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
67pub struct AMQPClass {
68    /// The id of the class
69    pub id: Identifier,
70    /// The methods of the class
71    pub methods: Vec<AMQPMethod>,
72    /// The name of the class
73    pub name: String,
74    /// The properties of the class
75    pub properties: Vec<AMQPProperty>,
76    /// Extra metadata for code generation
77    pub metadata: Value,
78}
79
80/// A method as defined in the AMQP specification
81#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
82pub struct AMQPMethod {
83    /// The id of the method
84    pub id: Identifier,
85    /// The arguments of the method
86    pub arguments: Vec<AMQPArgument>,
87    /// The name of the method
88    pub name: String,
89    /// Whether this method is synchronous or not
90    pub synchronous: Boolean,
91    /// Whether this method carries some content frames with it
92    pub content: Boolean,
93    /// Extra metadata for code generation
94    pub metadata: Value,
95    /// Whether this method is a reply or not
96    pub is_reply: bool,
97    /// Whether all the arguments have force_default or not
98    pub ignore_args: bool,
99    /// Whether this method can be sent from client to server
100    pub c2s: bool,
101    /// Whether this method can be received from server to client
102    pub s2c: bool,
103}
104
105/// An argument as defined in the AMQP specification
106#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
107pub enum AMQPArgument {
108    /// The argument is holding a value
109    Value(AMQPValueArgument),
110    /// The argument is holding flags
111    Flags(AMQPFlagsArgument),
112}
113
114impl AMQPArgument {
115    pub(crate) fn force_default(&self) -> bool {
116        match self {
117            AMQPArgument::Value(v) => v.force_default,
118            AMQPArgument::Flags(f) => f.force_default(),
119        }
120    }
121}
122
123/// An argument holding a value as defined in the AMQP specification
124#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
125pub struct AMQPValueArgument {
126    /// The type of the argument's value
127    #[serde(rename = "type")]
128    pub amqp_type: AMQPType,
129    /// The name of the argument's value
130    pub name: String,
131    /// The default value of the argument's value
132    pub default_value: Option<AMQPValue>,
133    /// The domain of the argument's value
134    pub domain: Option<String>,
135    /// Whether the default value is forced or not
136    pub force_default: bool,
137}
138
139/// An argument holding a flags as defined in the AMQP specification
140#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
141pub struct AMQPFlagsArgument {
142    /// Whether all the flags have force_default or not
143    pub ignore_flags: bool,
144    /// The actual flags
145    pub flags: Vec<AMQPFlagArgument>,
146}
147
148impl AMQPFlagsArgument {
149    pub(crate) fn force_default(&self) -> bool {
150        self.flags.iter().all(|f| f.force_default)
151    }
152}
153
154/// An argument holding a flag as defined in the AMQP specification
155#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
156pub struct AMQPFlagArgument {
157    /// The name of the flag
158    pub name: String,
159    /// The default value for the flag
160    pub default_value: Boolean,
161    /// Whether the default value is forced or not
162    pub force_default: bool,
163}
164
165/// A property as defined in the AMQP specification
166#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
167pub struct AMQPProperty {
168    /// The type of the property
169    #[serde(rename = "type")]
170    pub amqp_type: AMQPType,
171    /// The name of the property
172    pub name: String,
173}