Skip to main content

cyclonedds/
lib.rs

1//! The official Rust binding for
2//! [Cyclone DDS](https://github.com/eclipse-cyclonedds/cyclonedds).
3//!
4//! DDS (Data Distribution Service) is a publish-subscribe middleware standard
5//! for real-time, data-centric communication. It is used in a variety of
6//! mission critical applications in domains such as aerospace, defense,
7//! autonomous systems (e.g. vehicles, robotics), industrial control, smart
8//! energy grids, transportation, simulation, and medical devices.
9//!
10//! [`Participants`](Participant) within a specific [`Domain`] discover each
11//! other automatically via the DDSI/RTPS discovery protocol. Once two endpoints
12//! sharing the same topic name, type information, and compatible
13//! [`Quality of Service`][QoS] (`QoS`) discover each other, the middleware
14//! establishes a connection between them.
15//!
16//! [`Publishers`](Publisher) and [`Subscribers`](Subscriber) allow you to group
17//! [`Writers`](Writer) and [`Readers`](Reader) respectively to allow you to set
18//! their collective behavior. These [`Writers`](Writer) and [`Readers`](Reader)
19//! exchange typed samples via [`Topics`](Topic).
20//!
21//! ```text
22//!                             DOMAIN
23//!                                │
24//!             ┌──────────────────┴──────────────────┐
25//!             │                                     │
26//!        PARTICIPANT                           PARTICIPANT
27//!             │      T ≡ struct Position {x, y}     │
28//!        ┌────┴────┐                           ┌────┴────┐
29//!        │         │                           │         │
30//!   PUBLISHER   TOPIC<T> ═══════════════════ TOPIC<T>  SUBSCRIBER
31//!        │         ║                           ║         │
32//!        │     "Position"                 "Position"     │
33//!        │         ║                           ║         │
34//!     WRITER<T> ═══╝                           ╚═══ READER<T>
35//!          ╰───────── matched via Topic<T> ─────────╯
36//!          Node 01                               Node 02
37//!         ─────────                             ─────────
38//! ```
39//!
40//! Data delivery characteristics, such as how samples are buffered,
41//! retransmitted, and received, are controlled via [`Quality of Service`][QoS],
42//! a collection of
43//! [`QoS policies`](qos::policy) that configure characteristics such as:
44//!
45//! - [`durability`](qos::policy::Durability) (whether late-joining readers
46//!   receive historical samples)
47//!
48//! - [`reliability`](qos::policy::Reliability) (best-effort vs reliable
49//!   delivery)
50//!
51//! - [`history depth`](qos::policy::History) (the number of samples to store in
52//!   history)
53//!
54//! - [`deadline`](qos::policy::Deadline) (whether a signal should be generated
55//!   when a sample is not received within a specified period)
56//!
57//! Policies are set independently on the writer and reader side, and
58//! compatibility is checked at discovery time. A writer's offered [`QoS`] must
59//! be compatible with a reader's requested [`QoS`] for the two endpoints to
60//! match.
61//!
62//! There are a variety of other elements to the DDS API such as:
63//!
64//! [`WaitSets`](WaitSet): to allow you to block until a particular status
65//! occurs on a DDS entity. [`Listeners`](Listener): to notify applications of a
66//! change in the status of a particular entity.
67//! [`GuardConditions`](GuardCondition), `StatusConditions`,
68//! [`ReadConditions`](ReadCondition), and [`QueryConditions`](QueryCondition):
69//! Mechanisms to trigger the condition associated with a waitset.
70//!
71//! See the [DDS Specification](https://www.omg.org/spec/DDS/1.4/About-DDS/) and the [OMG DDS Wiki](https://www.omgwiki.org/ddsf/doku.php?id=ddsf:public:guidebook:01_front:4_toc) for these other elements and see the rest of the Rust Documentation for what is supported by this API.//!
72//!
73//! # Getting started
74//!
75//! Every DDS application begins with a [`Domain`] and a [`Participant`]:
76//!
77//! ```
78//! use cyclonedds::{Domain, Participant};
79//!
80//! let domain = Domain::default();
81//! let participant = Participant::new(&domain)?;
82//! # Ok::<_, cyclonedds::Error>(())
83//! ```
84//!
85//! Types that can be used as a topic payload must implement the [`Topicable`]
86//! trait, either manually or via the
87//! [`Topicable`](cyclonedds_macros::Topicable) derive macro. Once you have a
88//! topic, create a [`Writer`] or [`Reader`] directly via `new` or through their
89//! builders to set [`QoS`] or to associate specific publishers or subscribers.
90//! You can then create samples and write them via the writer and read those
91//! samples back via the reader.
92//!
93//! ```
94//! # use cyclonedds::{Domain, Participant};
95//! # let domain = Domain::default();
96//! # let participant = Participant::new(&domain)?;
97//! # #[derive(
98//! #     cyclonedds::Topicable, serde::Serialize, serde::Deserialize, Clone, Debug, Default,
99//! # )]
100//! # struct MyData {
101//! #     x: i32,
102//! # }
103//! use cyclonedds::qos;
104//! use cyclonedds::{QoS, Reader, Subscriber, Topic, Writer};
105//!
106//! let topic = Topic::<MyData>::new(&participant, "MyTopic")?;
107//!
108//! let qos = QoS::new()
109//!     .with_reliability(qos::policy::Reliability::BestEffort)
110//!     .with_history(qos::policy::History::KeepLast { depth: 10 });
111//!
112//! let subscriber = Subscriber::builder(&participant).with_qos(&qos).build()?;
113//!
114//! let writer = Writer::builder(&topic).with_qos(&qos).build()?;
115//! let reader = Reader::builder(&topic)
116//!     .with_qos(&qos)
117//!     .with_subscriber(&subscriber)
118//!     .build()?;
119//!
120//! for x in 0..10 {
121//!     let sample = MyData { x };
122//!     writer.write(&sample)?;
123//! }
124//! # assert_eq!(10, reader.read()?.len());
125//!
126//! // Does not remove the samples from the history,
127//! // and does not update metadata.
128//! for sample in reader.peek()? {
129//!     // process sample
130//! }
131//!
132//! // Does not remove the samples from the history,
133//! // but does update metadata.
134//! for sample in reader.read()? {
135//!     // process sample
136//! }
137//!
138//! // Removes the samples from the history,
139//! // and updates metadata.
140//! for sample in reader.take()? {
141//!     // process sample
142//! }
143//!
144//! # assert_eq!(0, reader.read()?.len());
145//! # Ok::<_, cyclonedds::Error>(())
146//! ```
147//!
148//! For further reading, see the [Cyclone DDS
149//! documentation](https://cyclonedds.io), the [OMG DDS
150//! specification](https://www.omg.org/spec/DDS/), and the
151//! [`examples`](https://github.com/eclipse-cyclonedds/cyclonedds-rust/tree/master/cyclonedds/examples).
152
153// NOTE: this is specified here rather than in the common lints within the workspace `Cargo.toml`
154// because excluding it for the examples and integration tests is problematic.
155#![deny(unused_crate_dependencies)]
156// NOTE: active lint levels are defined in the workspace `Cargo.toml`. J
157// These `allow`s for the test exist for lints that significantly reduce test readability or
158// ergonomics.
159#![cfg_attr(
160    test,
161    allow(
162        clippy::cast_sign_loss,
163        clippy::cognitive_complexity,
164        clippy::indexing_slicing,
165        clippy::too_many_lines,
166        clippy::undocumented_unsafe_blocks,
167    )
168)]
169
170pub mod cdr_bounds;
171mod domain;
172mod duration;
173pub mod entity;
174mod error;
175mod guard_condition;
176pub mod listener;
177mod participant;
178mod publisher;
179pub mod qos;
180mod query_condition;
181mod read_condition;
182mod reader;
183pub mod sample;
184pub mod state;
185pub mod status;
186mod subscriber;
187mod time;
188mod topic;
189mod topicable;
190mod waitset;
191mod writer;
192
193pub use cyclonedds_macros::Topicable;
194pub use domain::Domain;
195pub use duration::Duration;
196pub use error::{Error, Result};
197pub use guard_condition::GuardCondition;
198pub use listener::{
199    Listener, PublisherListener, ReaderListener, SubscriberListener, TopicListener, WriterListener,
200};
201pub use participant::Participant;
202pub use publisher::Publisher;
203pub use qos::QoS;
204pub use query_condition::QueryCondition;
205pub use read_condition::ReadCondition;
206pub use reader::Reader;
207pub use state::State;
208pub use status::bitflags::Status;
209pub use subscriber::Subscriber;
210pub use time::Time;
211pub use topic::Topic;
212pub use topicable::{Key, Topicable};
213pub use waitset::WaitSet;
214pub use writer::Writer;
215
216pub mod builder {
217    //! Builder types for constructing DDS entities with custom `QoS` and
218    //! listeners.
219    //!
220    //! Each builder is also accessible via the `builder` associated function on
221    //! its corresponding entity type.
222    pub use crate::participant::ParticipantBuilder;
223    pub use crate::publisher::PublisherBuilder;
224    pub use crate::reader::ReaderBuilder;
225    pub use crate::subscriber::SubscriberBuilder;
226    pub use crate::topic::TopicBuilder;
227    pub use crate::writer::WriterBuilder;
228}
229
230#[cfg(feature = "internal")]
231pub mod internal;
232#[cfg(not(feature = "internal"))]
233mod internal;
234
235#[cfg(test)]
236mod tests;