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};