asyncapi/
operation_binding.rs

1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4use crate::Schema;
5
6/// Map describing protocol-specific definitions for an operation.
7#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
8pub struct OperationBinding {
9    /// Protocol-specific information for an HTTP operation
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub http: Option<HTTPOperationBinding>,
12    /// Protocol-specific information for a WebSockets operation
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub ws: Option<WebSocketsOperationBinding>,
15    /// Protocol-specific information for a Kafka operation
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub kafka: Option<KafkaOperationBinding>,
18    /// Protocol-specific information for an Anypoint MQ operation.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub anypointmq: Option<AnyPointMQOperationBinding>,
21    /// Protocol-specific information for an AMPQ operation
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub amqp: Option<AMQPOperationBinding>,
24    /// Protocol-specific information for an AMQP 1.0 operation
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub amqp1: Option<AMQP1OperationBinding>,
27    /// Protocol-specific information for an MQTT operation
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub mqtt: Option<MQTTOperationBinding>,
30    /// Protocol-specific information for an MQTT 5 operation
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub mqtt5: Option<MQTT5OperationBinding>,
33    /// Protocol-specific information for a NATS operation
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub nats: Option<NATSOperationBinding>,
36    /// Protocol-specific information for a JMS operation
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub jms: Option<JMSOperationBinding>,
39    /// Protocol-specific information for an SNS operation
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub sns: Option<SNSOperationBinding>,
42    /// Protocol-specific information for a Solace operation
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub solace: Option<SolaceOperationBinding>,
45    /// Protocol-specific information for an SQS operation
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub sqs: Option<SQSOperationBinding>,
48    /// Protocol-specific information for a STOMP operation
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub stomp: Option<STOMPOperationBinding>,
51    /// Protocol-specific information for a Redis operation
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub redis: Option<RedisOperationBinding>,
54    /// Protocol-specific information for a Mercure operation
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub mercure: Option<MercureOperationBinding>,
57    /// This object can be extended with
58    /// [Specification Extensions](https://www.asyncapi.com/docs/specifications/v2.3.0#specificationExtensions).
59    #[serde(flatten)]
60    pub extensions: IndexMap<String, serde_json::Value>,
61}
62
63///
64///
65/// # Examples
66/// ```yaml
67/// channels:
68///   /employees:
69///     subscribe:
70///       bindings:
71///         http:
72///           type: request
73///           method: GET
74///           query:
75///             type: object
76///             required:
77///               - companyId
78///             properties:
79///               companyId:
80///                 type: number
81///                 minimum: 1
82///                 description: The Id of the company.
83///             additionalProperties: false
84///           bindingVersion: '0.1.0'
85/// ```
86#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
87#[serde(rename_all = "camelCase")]
88pub struct HTTPOperationBinding {
89    /// Required. Type of operation. Its value MUST be either `request` or `response`.
90    #[serde(rename = "type")]
91    pub typ: String,
92    /// When `type` is `request`, this is the HTTP method, otherwise it MUST be ignored.
93    /// Its value MUST be one of `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`,
94    /// `OPTIONS`, `CONNECT`, and `TRACE`.
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub method: Option<String>,
97    /// A Schema object containing the definitions for each query parameter.
98    /// This schema MUST be of type `object` and have a `properties` key.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub query: Option<Schema>,
101    /// The version of this binding. If omitted, "latest" MUST be assumed.
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub binding_version: Option<String>,
104}
105
106/// This object MUST NOT contain any properties. Its name is reserved for future use.
107#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
108pub struct WebSocketsOperationBinding {}
109
110/// This object contains information about the operation representation in Kafka.
111///
112/// # Examples
113///
114/// ```yaml
115/// channels:
116///   user-signedup:
117///     publish:
118///       bindings:
119///         kafka:
120///           groupId:
121///             type: string
122///             enum: ['myGroupId']
123///           clientId:
124///             type: string
125///             enum: ['myClientId']
126///           bindingVersion: '0.1.0'
127/// ```
128#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
129#[serde(rename_all = "camelCase")]
130pub struct KafkaOperationBinding {
131    /// Id of the consumer group.
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub group_id: Option<Schema>,
134    /// Id of the consumer inside a consumer group.
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub client_id: Option<Schema>,
137    /// The version of this binding. If omitted, "latest" MUST be assumed.
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub binding_version: Option<String>,
140}
141
142/// This object MUST NOT contain any properties. Its name is reserved for future use.
143#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
144pub struct AnyPointMQOperationBinding {}
145
146/// This object contains information about the operation representation in AMQP.
147///
148/// # Examples
149///
150/// ```yaml
151/// channels:
152///   user/signup:
153///     publish:
154///       bindings:
155///         amqp:
156///           expiration: 100000
157///           userId: guest
158///           cc: ['user.logs']
159///           priority: 10
160///           deliveryMode: 2
161///           mandatory: false
162///           bcc: ['external.audit']
163///           replyTo: user.signedup
164///           timestamp: true
165///           ack: false
166///           bindingVersion: 0.2.0
167/// ```
168#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
169#[serde(rename_all = "camelCase")]
170pub struct AMQPOperationBinding {
171    /// TTL (Time-To-Live) for the message. It MUST be greater than or equal to zero.
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub expiration: Option<i32>,
174    /// Identifies the user who has sent the message.
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub user_id: Option<String>,
177    /// The routing keys the message should be routed to at the time of publishing.
178    #[serde(default, skip_serializing_if = "Vec::is_empty")]
179    pub cc: Vec<String>,
180    /// A priority for the message.
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub priority: Option<i32>,
183    /// Delivery mode of the message. Its value MUST be either 1 (transient) or 2 (persistent).
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub delivery_mode: Option<i32>,
186    /// Whether the message is mandatory or not.
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub mandatory: Option<bool>,
189    /// Like [cc](https://github.com/asyncapi/bindings/blob/master/amqp/README.md#operationBindingObjectCC) but consumers will not receive this information.
190    #[serde(default, skip_serializing_if = "Vec::is_empty")]
191    pub bcc: Vec<String>,
192    /// Name of the queue where the consumer should send the response.
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub reply_to: Option<String>,
195    /// Whether the message should include a timestamp or not.
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub timestamp: Option<bool>,
198    /// Whether the consumer should ack the message or not.
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub ack: Option<bool>,
201    /// The version of this binding. If omitted, "latest" MUST be assumed.
202    #[serde(skip_serializing_if = "Option::is_none")]
203    pub binding_version: Option<String>,
204}
205
206/// This object MUST NOT contain any properties. Its name is reserved for future use.
207#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
208pub struct AMQP1OperationBinding {}
209
210/// This object contains information about the operation representation in MQTT.
211///
212/// # Examples
213///
214/// ```yaml
215/// channels:
216///   user/signup:
217///     publish:
218///       bindings:
219///         mqtt:
220///           qos: 2
221///           retain: true
222///           bindingVersion: 0.1.0
223/// ```
224#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
225#[serde(rename_all = "camelCase")]
226pub struct MQTTOperationBinding {
227    /// Defines the Quality of Service (QoS) levels for the message flow between client
228    /// and server. Its value MUST be either 0 (At most once delivery),
229    /// 1 (At least once delivery), or 2 (Exactly once delivery).
230    #[serde(skip_serializing_if = "Option::is_none")]
231    pub qos: Option<i32>,
232    /// Whether the broker should retain the message or not.
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub retain: Option<bool>,
235    /// The version of this binding. If omitted, "latest" MUST be assumed.
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub binding_version: Option<String>,
238}
239
240/// This object MUST NOT contain any properties. Its name is reserved for future use.
241#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
242pub struct MQTT5OperationBinding {}
243
244#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
245#[serde(rename_all = "camelCase")]
246pub struct NATSOperationBinding {
247    /// Defines the name of the queue to use. It MUST NOT exceed 255 characters.
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub queue: Option<String>,
250    /// The version of this binding. If omitted, "latest" MUST be assumed.
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub binding_version: Option<String>,
253}
254
255/// This object MUST NOT contain any properties. Its name is reserved for future use.
256#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
257pub struct JMSOperationBinding {}
258
259/// This object MUST NOT contain any properties. Its name is reserved for future use.
260#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
261pub struct SNSOperationBinding {}
262
263/// We need the ability to support several bindings for each operation, see the
264/// [Example](https://github.com/asyncapi/bindings/tree/master/solace#example)
265/// section for details.
266#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
267#[serde(rename_all = "camelCase")]
268pub struct SolaceOperationBinding {
269    /// The current version is 0.2.0
270    #[serde(skip_serializing_if = "Option::is_none")]
271    pub binding_version: Option<String>,
272    #[serde(default, skip_serializing_if = "Vec::is_empty")]
273    pub destinations: Vec<SolaceDestination>,
274}
275
276/// Each destination has the following structure. Note that bindings under a
277/// 'subscribe' operation define the behaviour of publishers, and those under a
278/// 'publish' operation define how subscribers are configured.
279#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
280#[serde(rename_all = "camelCase")]
281pub struct SolaceDestination {
282    /// 'queue' or 'topic'. If the type is queue, then the subscriber can bind
283    /// to the queue, which in turn will subscribe to the topic as represented
284    /// by the channel name or to the provided topicSubscriptions.
285    #[serde(skip_serializing_if = "Option::is_none")]
286    destination_type: Option<SolaceDestinationType>,
287    #[serde(skip_serializing_if = "Option::is_none")]
288    delivery_mode: Option<SolaceDestinationDeliveryMode>,
289    #[serde(skip_serializing_if = "Option::is_none")]
290    queue: Option<SolaceDestinationQueue>,
291    #[serde(skip_serializing_if = "Option::is_none")]
292    topic: Option<SolaceDestinationTopic>,
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
296pub enum SolaceDestinationType {
297    Queue,
298    Topic,
299}
300
301/// 'direct' or 'persistent'. This determines the quality of service for
302/// publishing messages as documented
303/// [here](https://docs.solace.com/PubSub-Basics/Core-Concepts-Message-Delivery-Modes.htm).
304/// Default is 'persistent'.
305#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
306pub enum SolaceDestinationDeliveryMode {
307    Direct,
308    Persistent,
309}
310
311impl Default for SolaceDestinationDeliveryMode {
312    fn default() -> Self {
313        SolaceDestinationDeliveryMode::Persistent
314    }
315}
316
317#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
318#[serde(rename_all = "camelCase")]
319pub struct SolaceDestinationQueue {
320    /// The name of the queue, only applicable when destinationType is 'queue'.
321    #[serde(skip_serializing_if = "Option::is_none")]
322    name: Option<String>,
323    /// A list of topics that the queue subscribes to, only applicable when
324    /// destinationType is 'queue'. If none is given, the queue subscribes to
325    /// the topic as represented by the channel name.
326    #[serde(default, skip_serializing_if = "Vec::is_empty")]
327    topic_subscriptions: Vec<String>,
328    /// 'exclusive' or 'nonexclusive'. This is documented
329    /// [here](https://docs.solace.com/PubSub-Basics/Endpoints.htm).
330    /// Only applicable when destinationType is 'queue'.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    access_type: Option<SolaceDestinationQueueAccessType>,
333}
334
335#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
336pub enum SolaceDestinationQueueAccessType {
337    Exclusive,
338    Nonexclusive,
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
342#[serde(rename_all = "camelCase")]
343pub struct SolaceDestinationTopic {
344    /// A list of topics that the client subscribes to, only applicable when
345    /// destinationType is 'topic'. If none is given, the client subscribes to
346    /// the topic as represented by the channel name.
347    topic_subscriptions: Vec<String>,
348}
349
350/// This object MUST NOT contain any properties. Its name is reserved for future use.
351#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
352pub struct SQSOperationBinding {}
353
354/// This object MUST NOT contain any properties. Its name is reserved for future use.
355#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
356pub struct STOMPOperationBinding {}
357
358/// This object MUST NOT contain any properties. Its name is reserved for future use.
359#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
360pub struct RedisOperationBinding {}
361
362/// This object MUST NOT contain any properties. Its name is reserved for future use.
363#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
364pub struct MercureOperationBinding {}