Skip to main content

mom_rpc/
lib.rs

1//! Transport-agnostic async RPC over message-oriented middleware.
2//!
3//! This library provides a unified `RpcBroker` type for implementing RPC patterns
4//! over pub/sub systems like MQTT, AMQP, and DDS. It handles correlation ID
5//! generation, request/response matching, timeout handling, and concurrent
6//! request processing.
7//!
8//! # Supported Transports
9//!
10//! | Transport            | Description                       | Enable Flag          |
11//! |:---------------------|:----------------------------------|:---------------------|
12//! | **Memory** (default) | In-process testing transport      | **N/A** (always on)  |
13//! |                      |                                   |                      |
14//! | **AMQP via lapin**   | RabbitMQ and AMQP 0-9-1 brokers   | `transport_lapin`    |
15//! | **DDS via dust_dds** | Brokerless peer-to-peer transport | `transport_dust_dds` |
16//! | **MQTT via rumqttc** | MQTT broker-based transport       | `transport_rumqttc`  |
17//! | **Redis via redis**  | Redis Pub/Sub transport           | `transport_redis`    |
18//!
19//! **Note:** The `logging` feature (enabled by default) provides diagnostic output via `tracing`.
20//! To disable logging, use `default-features = false` in your `Cargo.toml`:
21//!
22//! ```toml
23//! [dependencies]
24//! mom-rpc = { version = "0.9", default-features = false, features = ["transport_rumqttc"] }
25//! ```
26//!
27//! # Quick Start
28//!
29//! ```no_run
30//! use mom_rpc::{TransportBuilder, RpcBrokerBuilder, Result};
31//! use serde::{Deserialize, Serialize};
32//!
33//! #[derive(Debug, Serialize, Deserialize)]
34//! struct ReadTemperature { unit: TemperatureUnit }
35//!
36//! #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
37//! enum TemperatureUnit { Celsius, Fahrenheit }
38//!
39//! #[derive(Debug, Serialize, Deserialize)]
40//! struct SensorReading { value: f32, unit: String, timestamp_ms: u64 }
41//!
42//! #[tokio::main]
43//! async fn main() -> Result<()> {
44//!     //
45//!     let transport = TransportBuilder::new()
46//!         .uri("memory://")
47//!         .node_id("env-sensor-42")
48//!         .full_duplex()
49//!         .build()
50//!         .await?;
51//!
52//!     let server = RpcBrokerBuilder::new(transport.clone()).build()?;
53//!     server.register_rpc_handler("read_temperature", |req: ReadTemperature| async move {
54//!         let celsius = 22.0_f32;
55//!         let (value, unit) = match req.unit {
56//!             TemperatureUnit::Celsius => (celsius, "C"),
57//!             TemperatureUnit::Fahrenheit => (celsius * 9.0 / 5.0 + 32.0, "F"),
58//!         };
59//!         Ok(SensorReading { value, unit: unit.to_string(), timestamp_ms: 0 })
60//!     })?;
61//!     let _handle = server.spawn()?;
62//!
63//!     let client = RpcBrokerBuilder::new(transport).build()?;
64//!     let resp: SensorReading = client
65//!         .request_to("env-sensor-42", "read_temperature", ReadTemperature {
66//!             unit: TemperatureUnit::Celsius,
67//!         }).await?;
68//!     println!("Temperature: {} {}", resp.value, resp.unit);
69//!
70//!     Ok(())
71//! }
72//! ```
73//!
74//! # Examples
75//!
76//! See the [examples/](https://github.com/JohnBasrai/mom-rpc/blob/main/examples/)
77//!  - `examples/sensor_client.rs`
78//!  - `examples/sensor_fullduplex.rs`
79//!  - `examples/sensor_memory.rs`
80//!  - `examples/sensor_server.rs`
81
82#![cfg_attr(
83    test,
84    allow(
85        clippy::unwrap_used,
86        clippy::expect_used,
87        clippy::panic,
88        clippy::panic_in_result_fn
89    )
90)]
91
92////////////////////////////////////////
93// Submodules
94////////////////////////////////////////
95
96mod broker;
97mod broker_builder;
98mod broker_mode;
99mod domain;
100mod retry;
101mod transport;
102mod transport_builder;
103
104mod correlation;
105mod error;
106
107////////////////////////////////////////
108// Public API
109////////////////////////////////////////
110
111pub use broker::RpcBroker;
112pub use broker_builder::RpcBrokerBuilder;
113pub use broker_mode::BrokerMode;
114pub(crate) use retry::RetryConfig;
115pub use transport_builder::TransportBuilder;
116
117pub use correlation::CorrelationId;
118pub use error::{Result, RpcError};
119
120pub use domain::{
121    // ---
122    Address,
123    Envelope,
124    Subscription,
125    SubscriptionHandle,
126    Transport,
127    TransportBase,
128    TransportConfig,
129    TransportMode,
130    TransportPtr,
131};
132
133////////////////////////////////////////
134// Transport factory functions
135////////////////////////////////////////
136
137// Memory transport testing utilities
138// WARNING: MemoryHub and create_memory_transport_with_hub are exposed only for
139// mom-rpc's own integration tests and may change without notice.
140// Production code should use TransportBuilder.
141pub use transport::create_memory_transport_with_hub;
142pub use transport::MemoryHub;
143
144// Protocol transport factories - internal only; users go through TransportBuilder
145pub(crate) use transport::create_dust_dds_transport;
146pub(crate) use transport::create_lapin_transport;
147pub(crate) use transport::create_memory_transport;
148pub(crate) use transport::create_redis_transport;
149pub(crate) use transport::create_rumqttc_transport;
150
151////////////////////////////////////////
152// Internal helpers
153////////////////////////////////////////
154
155pub(crate) use retry::retry_with_backoff;
156
157mod macros;
158pub(crate) use macros::{log_debug, log_error, log_info, log_warn};