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//! [](https://crates.io/crates/fe2o3-amqp)
8//! [](https://docs.rs/fe2o3-amqp/latest/fe2o3_amqp/)
9//! [](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}