Skip to content

Commit 2b9e79c

Browse files
docs: align Rust guide structure with JS (#4)
* docs: align Rust guide structure with JS * Make `guide` doc-only, flatten it * PR feedback * PR feedback (tech writer edits) * Align wording with existing JS docs * Revert internal .md files * Add information to valid info fields --------- Co-authored-by: Alejandro Núñez <alejnp@rti.com>
1 parent 332b68a commit 2b9e79c

File tree

13 files changed

+826
-74
lines changed

13 files changed

+826
-74
lines changed

docs/guide/advanced.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Advanced operations
2+
3+
This section collects less common operations that are still useful in
4+
production applications.
5+
6+
## Write parameters
7+
8+
[`crate::Output::write_with_params`] accepts a [`crate::WriteParams`] struct
9+
that can change the write action (`write`, `dispose`, `unregister`) and attach
10+
identity or timestamp metadata.
11+
12+
The available constructors are:
13+
14+
* [`crate::WriteParams::write`]
15+
* [`crate::WriteParams::dispose`]
16+
* [`crate::WriteParams::unregister`]
17+
18+
## Waiting and matching
19+
20+
* [`crate::Connector::wait_for_data`]: wait for any input to have data.
21+
* [`crate::Input::wait_for_publications`]: wait for matched writers.
22+
* [`crate::Output::wait_for_subscriptions`]: wait for matched readers.
23+
* [`crate::Output::wait`]: wait for acknowledgments.
24+
25+
Both `Input` and `Output` provide JSON helpers to inspect matches:
26+
27+
* [`crate::Input::display_matched_publications`]
28+
* [`crate::Output::display_matched_subscriptions`]
29+
30+
## Loan management
31+
32+
If you call [`crate::Input::take`], you can return the loan with
33+
[`crate::Input::return_loan`] after processing to release native resources.

docs/guide/configuration.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Configuration
2+
3+
RTI Connector for Rust uses an XML configuration file to define participants,
4+
readers, writers, topics, types, and QoS. The XML schema is the same one used
5+
by RTI Connext DDS XML-Based Application Creation.
6+
7+
For background on the XML format, see the
8+
[RTI XML-Based Application Creation guide](https://community.rti.com/static/documentation/connext-dds/current/doc/manuals/connext_dds_professional/xml_application_creation/index.htm).
9+
10+
## Loading a configuration
11+
12+
Create a connector by passing a participant name and the XML file path:
13+
14+
```rust
15+
use rtiddsconnector::Connector;
16+
17+
fn load_config() -> rtiddsconnector::ConnectorFallible {
18+
let _connector = Connector::new("MyLibrary::MyParticipant", "App.xml")?;
19+
Ok(())
20+
}
21+
```
22+
23+
The `config_name` must match a `<domain_participant>` element in the XML.
24+
25+
## XML tags and Connector API mapping
26+
27+
The table below summarizes the most common XML tags and how they map to the
28+
Connector API:
29+
30+
| XML Tag | DDS Concept | Connector API |
31+
| --- | --- | --- |
32+
| `<types>` | Data types | Types used by `Input` and `Output` |
33+
| `<domain_library>`, `<domain>`, `<register_type>`, `<topic>` | Domain, Topic | Defines the domain and topics used by `Connector` |
34+
| `<domain_participant_library>`, `<domain_participant>` | DomainParticipant | Loaded by `Connector::new` |
35+
| `<publisher>`, `<data_writer>` | Publisher, DataWriter | Each `<data_writer>` defines an `Output` |
36+
| `<subscriber>`, `<data_reader>` | Subscriber, DataReader | Each `<data_reader>` defines an `Input` |
37+
| `<qos_library>`, `<qos_profile>` | QoS | QoS for `Connector`, `Output`, and `Input` |
38+
39+
## Types
40+
41+
Types are defined under `<types>` and associated with topics. Example:
42+
43+
```xml
44+
<types>
45+
<struct name="ShapeType">
46+
<member name="color" type="string" stringMaxLength="128" key="true"/>
47+
<member name="x" type="int32"/>
48+
<member name="y" type="int32"/>
49+
<member name="shapesize" type="int32"/>
50+
</struct>
51+
</types>
52+
```
53+
54+
You can define types in IDL and convert them to XML with `rtiddsgen`:
55+
56+
```
57+
rtiddsgen -convertToXml MyTypes.idl
58+
```
59+
60+
## Domain and topics
61+
62+
Domains register types and define topics:
63+
64+
```xml
65+
<domain_library name="MyDomainLibrary">
66+
<domain name="MyDomain" domain_id="0">
67+
<register_type name="ShapeType" type_ref="ShapeType"/>
68+
<topic name="Square" register_type_ref="ShapeType"/>
69+
</domain>
70+
</domain_library>
71+
```
72+
73+
## Participants, readers, and writers
74+
75+
Participants contain publishers and subscribers, which in turn manage individual
76+
writers and readers:
77+
78+
```xml
79+
<domain_participant_library name="MyParticipantLibrary">
80+
<domain_participant name="MyPubParticipant" domain_ref="MyDomainLibrary::MyDomain">
81+
<publisher name="MyPublisher">
82+
<data_writer name="MySquareWriter" topic_ref="Square" />
83+
</publisher>
84+
</domain_participant>
85+
86+
<domain_participant name="MySubParticipant" domain_ref="MyDomainLibrary::MyDomain">
87+
<subscriber name="MySubscriber">
88+
<data_reader name="MySquareReader" topic_ref="Square" />
89+
</subscriber>
90+
</domain_participant>
91+
</domain_participant_library>
92+
```
93+
94+
## QoS profiles
95+
96+
QoS can be configured at the profile level or per-entity. Example profile:
97+
98+
```xml
99+
<qos_library name="MyQosLibrary">
100+
<qos_profile name="MyQosProfile" is_default_qos="true">
101+
<datareader_qos>
102+
<reliability>
103+
<kind>RELIABLE_RELIABILITY_QOS</kind>
104+
</reliability>
105+
</datareader_qos>
106+
<datawriter_qos>
107+
<reliability>
108+
<kind>RELIABLE_RELIABILITY_QOS</kind>
109+
</reliability>
110+
</datawriter_qos>
111+
</qos_profile>
112+
</qos_library>
113+
```
114+
115+
## Examples in this repo
116+
117+
This repository includes XML examples you can adapt. For an example
118+
configuration file, see `examples/shapes/Shapes.xml`:
119+
120+
* `examples/MyApplication.xml`
121+
* `examples/shapes/Shapes.xml`

docs/guide/connector.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Connector lifecycle
2+
3+
This chapter covers creating a connector, acquiring inputs and outputs, and
4+
cleaning up native resources.
5+
6+
[`crate::Connector`] represents a DDS `DomainParticipant` configured from XML.
7+
It owns native resources and creates `Input` and `Output` handles.
8+
9+
## Importing the crate
10+
11+
To import the crate:
12+
13+
```rust
14+
use rtiddsconnector::{self, Connector};
15+
```
16+
17+
## Creating a connector
18+
19+
To create a connector, pass an XML file and a configuration name to
20+
[`crate::Connector::new`]:
21+
22+
```rust
23+
use rtiddsconnector::Connector;
24+
25+
fn create_connector() -> rtiddsconnector::ConnectorFallible {
26+
let _connector = Connector::new("MyLibrary::MyParticipant", "App.xml")?;
27+
Ok(())
28+
}
29+
```
30+
31+
The XML file defines your types, QoS profiles, and DDS entities. The call above
32+
loads a `<domain_participant>` from a `<domain_participant_library>`. For example:
33+
34+
```xml
35+
<domain_participant_library name="MyParticipantLibrary">
36+
<domain_participant name="MyParticipant" domain_ref="MyDomainLibrary::MyDomain">
37+
...
38+
</domain_participant>
39+
</domain_participant_library>
40+
```
41+
42+
See a complete example in `examples/MyApplication.xml`.
43+
44+
> **Note:** Operations on the same `Connector` or its contained entities are not
45+
> protected for multi-threaded access. See
46+
> [Threading and ownership](crate::guide::threading) for guidance.
47+
48+
## Closing a connector
49+
50+
There is no explicit `close()` method in Rust. Instead, `Connector`, `Input`, and
51+
`Output` are released when they go out of scope. The crate uses RAII to free
52+
native resources.
53+
54+
To force cleanup of Connext global resources at the end of a scope (for example,
55+
in tests), use [`crate::GlobalsDropGuard`].
56+
57+
## Getting inputs and outputs
58+
59+
Once you have created a connector, use [`crate::Connector::get_input`] and
60+
[`crate::Connector::get_output`] to retrieve inputs and outputs.
61+
62+
> **Note:** If the `<domain_participant>` you load contains both `<data_writer>`
63+
> and `<data_reader>` tags for the same topic and they have matching QoS, inputs
64+
> may receive data before you call `get_input`. To avoid this, configure the
65+
> `<subscriber>` that contains the `<data_reader>` with
66+
> `<subscriber_qos>/<entity_factory>/<autoenable_created_entities>` set to
67+
> `false`. Then inputs will only receive data after you call `get_input`.
68+
69+
See [Publishing data](crate::guide::output) and [Reading data](crate::guide::input)
70+
for the workflow that follows.

docs/guide/data.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Data access and Serde
2+
3+
RTI Connector exposes data as JSON under the hood, while also providing typed
4+
accessors for common primitive fields.
5+
6+
## Complex types and XML definitions
7+
8+
The types you read and write can include nested structs, sequences, arrays, and
9+
unions. These types are defined in XML following RTI's XML-Based Application
10+
Creation format. For details, see
11+
[RTI XML-Based Application Creation](https://community.rti.com/static/documentation/connext-dds/current/doc/manuals/connext_dds_professional/xml_application_creation/xml_based_app_creation_guide/UnderstandingXMLBased/XMLTagsConfigEntities.htm).
12+
13+
## JSON vs member access
14+
15+
You can access data member-by-member or as JSON. JSON access is convenient when
16+
working with large structures; member access is convenient when you only need a
17+
few fields.
18+
19+
* Set with JSON: [`crate::Instance::set_as_json`]
20+
* Get JSON: [`crate::Sample::get_value_json`]
21+
* Member access: [`crate::Instance::set_number`], [`crate::Instance::set_string`],
22+
[`crate::Sample::get_number`], [`crate::Sample::get_string`]
23+
24+
## Accessing basic members
25+
26+
Use typed setters/getters for numbers, booleans, and strings:
27+
28+
```rust
29+
use rtiddsconnector::{Instance, Sample};
30+
31+
fn set_basic(instance: &mut Instance) -> rtiddsconnector::ConnectorFallible {
32+
instance.set_number("my_long", 2.0)?;
33+
instance.set_boolean("my_boolean", true)?;
34+
instance.set_string("my_string", "Hello, World!")?;
35+
Ok(())
36+
}
37+
38+
fn get_basic(sample: &Sample) -> rtiddsconnector::ConnectorFallible {
39+
let _n = sample.get_number("my_long")?;
40+
let _b = sample.get_boolean("my_boolean")?;
41+
let _s = sample.get_string("my_string")?;
42+
Ok(())
43+
}
44+
```
45+
46+
## Accessing complex members
47+
48+
Examples of field-name syntax for nested members, arrays, sequences, and unions
49+
are available in the [Accessing the data (field-name syntax examples)](https://community.rti.com/static/documentation/connector/current/api/javascript/data.html#)
50+
chapter of the Connector for JavaScript API documentation.
51+
52+
## Type-independent access with SelectedValue
53+
54+
For dynamic access, use [`crate::Instance::set_value`] and
55+
[`crate::Sample::get_value`], which operate on [`crate::SelectedValue`]:
56+
57+
```rust
58+
use rtiddsconnector::{Instance, Sample, SelectedValue};
59+
60+
fn set_dynamic(instance: &mut Instance) -> rtiddsconnector::ConnectorFallible {
61+
instance.set_value("my_double", SelectedValue::Number(2.14))?;
62+
instance.set_value("my_boolean", SelectedValue::Boolean(true))?;
63+
instance.set_value("my_string", SelectedValue::String("Hello".to_string()))?;
64+
Ok(())
65+
}
66+
67+
fn get_dynamic(sample: &Sample) -> rtiddsconnector::ConnectorFallible {
68+
let _value = sample.get_value("my_double")?;
69+
Ok(())
70+
}
71+
```
72+
73+
## Performance guidance
74+
75+
Typed getters and setters are generally faster than dynamic access with
76+
`SelectedValue`. If you intend to access most or all members of a sample,
77+
using JSON (`set_as_json`/`get_value_json`) can be more convenient and efficient
78+
than setting or getting fields one by one.
79+
80+
## 64-bit integer limitations
81+
82+
RTI Connector uses a single number representation internally. This means that
83+
64-bit integers may lose precision when converted to the internal numeric type.
84+
If you need exact 64-bit integer values, consider representing them as strings
85+
in your data model and converting explicitly in your application.
86+
87+
## Typed serialization
88+
89+
If you want to work with Rust structs, use Serde:
90+
91+
* [`crate::Instance::serialize`]: serialize a struct and set it into the
92+
instance.
93+
* [`crate::Sample::deserialize`]: deserialize a sample into a struct.
94+
95+
These methods allow you to keep strongly-typed models in your application while
96+
still using the dynamic RTI Connector API.

docs/guide/errors.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Error handling
2+
3+
Most operations return [`crate::ConnectorResult<T>`] or
4+
[`crate::ConnectorFallible`]. When an operation fails, you receive a
5+
[`crate::ConnectorError`].
6+
7+
## Common patterns
8+
9+
```rust
10+
use rtiddsconnector::{Connector, ConnectorError};
11+
12+
fn try_connect() -> Result<(), ConnectorError> {
13+
let _connector = Connector::new("MyLibrary::MyParticipant", "App.xml")?;
14+
Ok(())
15+
}
16+
```
17+
18+
Use helper methods to detect common cases:
19+
20+
* [`crate::ConnectorError::is_timeout`]
21+
* [`crate::ConnectorError::is_entity_not_found`]
22+
* [`crate::ConnectorError::is_field_not_found`]
23+
* [`crate::ConnectorError::is_native_error`]
24+
25+
To inspect the last native error message, call
26+
[`crate::ConnectorError::last_error_message`].
27+
28+
## Timeout example
29+
30+
This example waits for data and treats a timeout as a non-fatal outcome.
31+
32+
```rust
33+
use rtiddsconnector::Input;
34+
35+
fn wait_with_timeout(input: &Input) -> rtiddsconnector::ConnectorFallible {
36+
match input.wait_with_timeout(std::time::Duration::from_secs(2)) {
37+
Ok(()) => Ok(()),
38+
Err(e) if e.is_timeout() => {
39+
println!("Timed out waiting for data");
40+
Ok(())
41+
}
42+
Err(e) => Err(e),
43+
}
44+
}
45+
```
46+
47+
## Native error details
48+
49+
If an operation fails because of a native RTI Connector error, the
50+
[`crate::ConnectorError`] will include the last error message from the native library.
51+
This can provide additional context when debugging configuration or data access
52+
issues.

0 commit comments

Comments
 (0)