fe2o3_amqp/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![deny(missing_docs, missing_debug_implementations)]
3#![warn(clippy::unused_async)]
4
5//! A rust implementation of AMQP 1.0 protocol based on serde and tokio.
6//!
7//! [![crate_version](https://img.shields.io/crates/v/fe2o3-amqp.svg?style=flat)](https://crates.io/crates/fe2o3-amqp)
8//! [![docs_version](https://img.shields.io/badge/docs-latest-blue.svg?style=flat)](https://docs.rs/fe2o3-amqp/latest/fe2o3_amqp/)
9//! [![discord](https://img.shields.io/discord/1016422034592497665?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2")](https://discord.gg/YMkaETwnFW)
10//!
11//! - [Quick Start](#quick-start)
12//! - [Documentation](https://docs.rs/fe2o3-amqp)
13//! - [Changelog](https://github.com/minghuaw/fe2o3-amqp/blob/main/fe2o3-amqp/Changelog.md)
14//! - [Examples](https://github.com/minghuaw/fe2o3-amqp/tree/main/examples)
15//!
16//! # Feature flags
17//!
18//! ```toml
19//! default = []
20//! ```
21//!
22//! | Feature | Description |
23//! |---------|-------------|
24//! |`"rustls"`| enables TLS integration with `tokio-rustls` and `rustls` |
25//! |`"native-tls"`| enables TLS integration with `tokio-native-tls` and `native-tls`|
26//! |`"acceptor"`| enables `ConnectionAcceptor`, `SessionAcceptor`, and `LinkAcceptor`|
27//! |`"transaction"`| enables `Controller`, `Transaction`, `OwnedTransaction` and `control_link_acceptor` |
28//! |`"scram"`| enables SCRAM auth |
29//! |`"tracing"`| enables logging with `tracing` |
30//! |`"log"`| enables logging with `log` |
31//!
32//! # Quick start
33//!
34//! 1. [Client](#client)
35//! 2. [Listener](#listener)
36//! 3. [WebSocket binding](#websocket)
37//!
38//! More examples including one showing how to use it with Azure Service Bus can be found on the
39//! [GitHub repo](https://github.com/minghuaw/fe2o3-amqp/tree/main/examples).
40//!
41//! ## Client
42//!
43//! Below is an example with a local broker
44//! ([`TestAmqpBroker`](https://github.com/Azure/amqpnetlite/releases/download/test_broker.1609/TestAmqpBroker.zip))
45//! listening on the localhost. The broker is executed with the following command
46//!
47//! ```powershell
48//! ./TestAmqpBroker.exe amqp://localhost:5672 /creds:guest:guest /queues:q1
49//! ```
50//!
51//! The following code requires the [`tokio`] async runtime added to the dependencies.
52//!
53//! ```rust,no_run
54//! use fe2o3_amqp::{Connection, Session, Sender, Receiver};
55//! use fe2o3_amqp::types::messaging::Outcome;
56//!
57//! #[tokio::main]
58//! async fn main() {
59//!     let mut connection = Connection::open(
60//!         "connection-1",                     // container id
61//!         "amqp://guest:guest@localhost:5672" // url
62//!     ).await.unwrap();
63//!     
64//!     let mut session = Session::begin(&mut connection).await.unwrap();
65//!     
66//!     // Create a sender
67//!     let mut sender = Sender::attach(
68//!         &mut session,           // Session
69//!         "rust-sender-link-1",   // link name
70//!         "q1"                    // target address
71//!     ).await.unwrap();
72//!     
73//!     // Create a receiver
74//!     let mut receiver = Receiver::attach(
75//!         &mut session,
76//!         "rust-receiver-link-1", // link name
77//!         "q1"                    // source address
78//!     ).await.unwrap();
79//!     
80//!     // Send a message to the broker and wait for outcome (Disposition)
81//!     let outcome: Outcome = sender.send("hello AMQP").await.unwrap();
82//!     outcome.accepted_or_else(|state| state).unwrap(); // Handle delivery outcome
83//!
84//!     // Send a message with batchable field set to true
85//!     let fut = sender.send_batchable("hello batchable AMQP").await.unwrap();
86//!     let outcome: Outcome = fut.await.unwrap(); // Wait for outcome (Disposition)
87//!     outcome.accepted_or_else(|state| state).unwrap(); // Handle delivery outcome
88//!
89//!     // Receive the message from the broker
90//!     let delivery = receiver.recv::<String>().await.unwrap();
91//!     receiver.accept(&delivery).await.unwrap();
92//!
93//!     sender.close().await.unwrap(); // Detach sender with closing Detach performatives
94//!     receiver.close().await.unwrap(); // Detach receiver with closing Detach performatives
95//!     session.end().await.unwrap(); // End the session
96//!     connection.close().await.unwrap(); // Close the connection
97//! }
98//! ```
99//!
100//! ## Listener
101//!
102//! ```rust,no_run
103//! use tokio::net::TcpListener;
104//! use fe2o3_amqp::acceptor::{ConnectionAcceptor, SessionAcceptor, LinkAcceptor, LinkEndpoint};
105//!
106//! #[tokio::main]
107//! async fn main() {
108//!     let tcp_listener = TcpListener::bind("localhost:5672").await.unwrap();
109//!     let connection_acceptor = ConnectionAcceptor::new("example-listener");
110//!
111//!     while let Ok((stream, addr)) = tcp_listener.accept().await {
112//!         let mut connection = connection_acceptor.accept(stream).await.unwrap();
113//!         let handle = tokio::spawn(async move {
114//!             let session_acceptor = SessionAcceptor::new();
115//!             while let Ok(mut session) = session_acceptor.accept(&mut connection).await{
116//!                 let handle = tokio::spawn(async move {
117//!                     let link_acceptor = LinkAcceptor::new();
118//!                     match link_acceptor.accept(&mut session).await.unwrap() {
119//!                         LinkEndpoint::Sender(sender) => { },
120//!                         LinkEndpoint::Receiver(recver) => { },
121//!                     }
122//!                 });
123//!             }
124//!         });
125//!     }
126//! }
127//! ```
128//!
129//! ## WebSocket
130//!
131//! [`fe2o3-amqp-ws`](https://crates.io/crates/fe2o3-amqp-ws) is needed for WebSocket binding
132//!
133//! ```rust,ignore
134//! use fe2o3_amqp::{
135//!     types::{messaging::Outcome, primitives::Value},
136//!     Connection, Delivery, Receiver, Sender, Session,
137//! };
138//! use fe2o3_amqp_ws::WebSocketStream;
139//!
140//! #[tokio::main]
141//! async fn main() {
142//!     let (ws_stream, _response) = WebSocketStream::connect("ws://localhost:5673")
143//!         .await
144//!         .unwrap();
145//!     let mut connection = Connection::builder()
146//!         .container_id("connection-1")
147//!         .open_with_stream(ws_stream)
148//!         .await
149//!         .unwrap();
150//!
151//!     connection.close().await.unwrap();
152//! }
153//! ```
154//!
155//! # More examples
156//!
157//! More examples of sending and receiving can be found on the [GitHub
158//! repo](https://github.com/minghuaw/fe2o3-amqp/tree/main/examples/). Please note that most
159//! examples requires a local broker running. One broker that can be used on Windows is
160//! [TestAmqpBroker](https://azure.github.io/amqpnetlite/articles/hello_amqp.html).
161//!
162//! # WebAssembly support
163//!
164//! Experimental support for `wasm32-unknown-unknown` target is added since "0.8.11" and requires use of
165//! `fe2o3-amqp-ws` to establish WebSocket connection to the broker. An example of sending and
166//! receiving message in a browser tab can be found
167//! [examples/wasm32-in-browser](https://github.com/minghuaw/fe2o3-amqp/tree/main/examples/wasm32-in-browser).
168//!
169//! # Components
170//!
171//! | Name | Description |
172//! |------|-------------|
173//! |`serde_amqp_derive`| Custom derive macro for described types as defined in AMQP1.0 protocol |
174//! |`serde_amqp`| AMQP1.0 serializer and deserializer as well as primitive types |
175//! |`fe2o3-amqp-types`| AMQP1.0 data types |
176//! |`fe2o3-amqp`| Implementation of AMQP1.0 `Connection`, `Session`, and `Link` |
177//! |`fe2o3-amqp-ext`| Extension types and implementations |
178//! |`fe2o3-amqp-ws` | WebSocket binding for `fe2o3-amqp` transport |
179//! |`fe2o3-amqp-management`| Experimental implementation of AMQP1.0 management |
180//! |`fe2o3-amqp-cbs`| Experimental implementation of AMQP1.0 CBS |
181//!
182//! # Minimum rust version supported
183//!
184//! 1.75.0
185
186#[macro_use]
187mod macros;
188
189pub(crate) mod control;
190pub(crate) mod endpoint;
191pub(crate) mod util;
192
193pub mod auth;
194pub mod connection;
195pub mod frames;
196pub mod link;
197pub mod sasl_profile;
198pub mod session;
199pub mod transport;
200
201cfg_acceptor! {
202    pub mod acceptor;
203}
204
205cfg_transaction! {
206    pub mod transaction;
207}
208
209pub mod types {
210    //! Re-exporting `fe2o3-amqp-types`
211    pub use fe2o3_amqp_types::*;
212}
213
214pub use connection::Connection;
215pub use link::{
216    delivery::{Delivery, Sendable},
217    Receiver, Sender,
218};
219pub use session::Session;
220
221type Payload = bytes::Bytes;
222
223cfg_not_wasm32! {
224    /// A marker trait to indicate that the type is `Send` bound in non-wasm32 targets
225    pub trait SendBound: Send {}
226    impl<T> SendBound for T where T: Send {}
227}
228
229cfg_wasm32! {
230    /// A marker trait that is implemented for all types in wasm32 targets
231    pub trait SendBound {}
232    impl<T> SendBound for T {}
233}