Skip to content

Commit b4e975c

Browse files
authored
Use latest stable Rust CI + Fix Test Errors (#420)
* Use latest stable Rust CI Signed-off-by: Michael X. Grey <[email protected]> * Fix quotation in doc Signed-off-by: Michael X. Grey <[email protected]> * Fix serde feature for vendored messages Signed-off-by: Michael X. Grey <[email protected]> * Fix formatting of lists in docs Signed-off-by: Michael X. Grey <[email protected]> * Update minimum supported Rust version based on the currently used language features Signed-off-by: Michael X. Grey <[email protected]> * Conform to clippy style guide Signed-off-by: Michael X. Grey <[email protected]> * Add rust toolchain as a matrix dimension Signed-off-by: Michael X. Grey <[email protected]> * Bump declaration of minimum supported rust version Signed-off-by: Michael X. Grey <[email protected]> * Limit the scheduled runs to once a week Signed-off-by: Michael X. Grey <[email protected]> * Define separate stable and minimal workflows because matrix does not work with reusable actions Signed-off-by: Michael X. Grey <[email protected]> * Reduce minimum version to 1.75 to target Noble Signed-off-by: Michael X. Grey <[email protected]> --------- Signed-off-by: Michael X. Grey <[email protected]> Signed-off-by: Michael X. Grey <[email protected]>
1 parent f45a66f commit b4e975c

File tree

8 files changed

+178
-36
lines changed

8 files changed

+178
-36
lines changed

.github/workflows/rust.yml renamed to .github/workflows/rust-minimal.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
name: Rust
1+
name: Rust Minimal
22

33
on:
44
push:
55
branches: [ main ]
66
pull_request:
77
branches: [ main ]
88
schedule:
9-
- cron: '0 0 * * *'
9+
# Run the CI at 02:22 UTC every Tuesday
10+
# We pick an arbitrary time outside of most of the world's work hours
11+
# to minimize the likelihood of running alongside a heavy workload.
12+
- cron: '22 2 * * 2'
1013

1114
env:
1215
CARGO_TERM_COLOR: always
@@ -51,7 +54,7 @@ jobs:
5154
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}
5255

5356
- name: Setup Rust
54-
uses: dtolnay/rust-toolchain@1.74.0
57+
uses: dtolnay/rust-toolchain@1.75
5558
with:
5659
components: clippy, rustfmt
5760

.github/workflows/rust-stable.yml

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Rust Stable
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
schedule:
9+
# Run the CI at 02:22 UTC every Tuesday
10+
# We pick an arbitrary time outside of most of the world's work hours
11+
# to minimize the likelihood of running alongside a heavy workload.
12+
- cron: '22 2 * * 2'
13+
14+
env:
15+
CARGO_TERM_COLOR: always
16+
17+
jobs:
18+
build:
19+
strategy:
20+
matrix:
21+
ros_distribution:
22+
- humble
23+
- iron
24+
- rolling
25+
include:
26+
# Humble Hawksbill (May 2022 - May 2027)
27+
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-humble-ros-base-latest
28+
ros_distribution: humble
29+
ros_version: 2
30+
# Iron Irwini (May 2023 - November 2024)
31+
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-iron-ros-base-latest
32+
ros_distribution: iron
33+
ros_version: 2
34+
# Rolling Ridley (June 2020 - Present)
35+
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-rolling-ros-base-latest
36+
ros_distribution: rolling
37+
ros_version: 2
38+
runs-on: ubuntu-latest
39+
continue-on-error: ${{ matrix.ros_distribution == 'rolling' }}
40+
container:
41+
image: ${{ matrix.docker_image }}
42+
steps:
43+
- uses: actions/checkout@v4
44+
45+
- name: Search packages in this repository
46+
id: list_packages
47+
run: |
48+
echo ::set-output name=package_list::$(colcon list --names-only)
49+
50+
- name: Setup ROS environment
51+
uses: ros-tooling/[email protected]
52+
with:
53+
required-ros-distributions: ${{ matrix.ros_distribution }}
54+
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}
55+
56+
- name: Setup Rust
57+
uses: dtolnay/rust-toolchain@stable
58+
with:
59+
components: clippy, rustfmt
60+
61+
- name: Install colcon-cargo and colcon-ros-cargo
62+
run: |
63+
sudo pip3 install git+https://github.com/colcon/colcon-cargo.git
64+
sudo pip3 install git+https://github.com/colcon/colcon-ros-cargo.git
65+
66+
- name: Check formatting of Rust packages
67+
run: |
68+
for path in $(colcon list | awk '$3 == "(ament_cargo)" { print $2 }'); do
69+
cd $path
70+
rustup toolchain install nightly
71+
cargo +nightly fmt -- --check
72+
cd -
73+
done
74+
75+
- name: Install cargo-ament-build
76+
run: |
77+
cargo install --debug cargo-ament-build
78+
79+
- name: Build and test
80+
id: build
81+
uses: ros-tooling/[email protected]
82+
with:
83+
package-name: ${{ steps.list_packages.outputs.package_list }}
84+
target-ros2-distro: ${{ matrix.ros_distribution }}
85+
vcs-repo-file-url: ros2_rust_${{ matrix.ros_distribution }}.repos
86+
87+
- name: Run clippy on Rust packages
88+
run: |
89+
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
90+
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
91+
for path in $(colcon list | awk '$3 == "(ament_cargo)" { print $2 }'); do
92+
cd $path
93+
echo "Running clippy in $path"
94+
# Run clippy for all features except generate_docs (needed for docs.rs)
95+
if [ "$(basename $path)" = "rclrs" ]; then
96+
cargo clippy --all-targets -F default,dyn_msg -- -D warnings
97+
else
98+
cargo clippy --all-targets --all-features -- -D warnings
99+
fi
100+
cd -
101+
done
102+
103+
- name: Run cargo test on Rust packages
104+
run: |
105+
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
106+
. install/setup.sh
107+
for path in $(colcon list | awk '$3 == "(ament_cargo)" && $1 != "examples_rclrs_minimal_pub_sub" && $1 != "examples_rclrs_minimal_client_service" && $1 != "rust_pubsub" { print $2 }'); do
108+
cd $path
109+
echo "Running cargo test in $path"
110+
# Run cargo test for all features except generate_docs (needed for docs.rs)
111+
if [ "$(basename $path)" = "rclrs" ]; then
112+
cargo test -F default,dyn_msg
113+
elif [ "$(basename $path)" = "rosidl_runtime_rs" ]; then
114+
cargo test -F default
115+
else
116+
cargo test --all-features
117+
fi
118+
cd -
119+
done
120+
121+
- name: Rustdoc check
122+
run: |
123+
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
124+
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
125+
for path in $(colcon list | awk '$3 == "(ament_cargo)" && $1 != "examples_rclrs_minimal_pub_sub" && $1 != "examples_rclrs_minimal_client_service" && $1 != "rust_pubsub" { print $2 }'); do
126+
cd $path
127+
echo "Running rustdoc check in $path"
128+
cargo rustdoc -- -D warnings
129+
cd -
130+
done

rclrs/Cargo.toml

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ authors = ["Esteve Fernandez <[email protected]>", "Nikolai Morin <nnmmgit@gmail
66
edition = "2021"
77
license = "Apache-2.0"
88
description = "A ROS 2 client library for developing robotics applications in Rust"
9-
rust-version = "1.63"
9+
rust-version = "1.75"
1010

1111
[lib]
1212
path = "src/lib.rs"
@@ -29,6 +29,10 @@ libloading = { version = "0.8", optional = true }
2929
# Needed for the Message trait, among others
3030
rosidl_runtime_rs = "0.4"
3131

32+
# Needed for serliazation and deserialization of vendored messages
33+
serde = { version = "1", optional = true, features = ["derive"] }
34+
serde-big-array = { version = "0.5.1", optional = true }
35+
3236
[dev-dependencies]
3337
# Needed for e.g. writing yaml files in tests
3438
tempfile = "3.3.0"
@@ -46,6 +50,7 @@ cfg-if = "1.0.0"
4650
[features]
4751
default = []
4852
dyn_msg = ["ament_rs", "libloading"]
53+
serde = ["dep:serde", "dep:serde-big-array", "rosidl_runtime_rs/serde"]
4954
# This feature is solely for the purpose of being able to generate documetation without a ROS installation
5055
# The only intended usage of this feature is for docs.rs builders to work, and is not intended to be used by end users
5156
generate_docs = ["rosidl_runtime_rs/generate_docs"]

rclrs/src/parameter.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ use std::{
2525
// Among the most relevant ones:
2626
//
2727
// * Parameter declaration returns an object which will be the main accessor to the parameter,
28-
// providing getters and, except for read only parameters, setters. Object destruction will
29-
// undeclare the parameter.
28+
// providing getters and, except for read only parameters, setters. Object destruction will
29+
// undeclare the parameter.
3030
// * Declaration uses a builder pattern to specify ranges, description, human readable constraints
31-
// instead of an ParameterDescriptor argument.
31+
// instead of an ParameterDescriptor argument.
3232
// * Parameters properties of read only and dynamic are embedded in their type rather than being a
33-
// boolean parameter.
33+
// boolean parameter.
3434
// * There are no runtime exceptions for common cases such as undeclared parameter, already
35-
// declared, or uninitialized.
35+
// declared, or uninitialized.
3636
// * There is no "parameter not set" type, users can instead decide to have a `Mandatory` parameter
37-
// that must always have a value or `Optional` parameter that can be unset.
37+
// that must always have a value or `Optional` parameter that can be unset.
3838
// * Explicit API for access to undeclared parameters by having a
39-
// `node.use_undeclared_parameters()` API that allows access to all parameters.
39+
// `node.use_undeclared_parameters()` API that allows access to all parameters.
4040

4141
#[derive(Clone, Debug)]
4242
struct ParameterOptionsStorage {
@@ -701,9 +701,9 @@ impl<'a> Parameters<'a> {
701701
/// Returns:
702702
/// * `Ok(())` if setting was successful.
703703
/// * [`Err(DeclarationError::TypeMismatch)`] if the type of the requested value is different
704-
/// from the parameter's type.
704+
/// from the parameter's type.
705705
/// * [`Err(DeclarationError::OutOfRange)`] if the requested value is out of the parameter's
706-
/// range.
706+
/// range.
707707
/// * [`Err(DeclarationError::ReadOnly)`] if the parameter is read only.
708708
pub fn set<T: ParameterVariant>(
709709
&self,

rclrs/src/parameter/range.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl From<()> for ParameterRanges {
3232
/// Usually only one of these ranges will be applied, but all have to be stored since:
3333
///
3434
/// * A dynamic parameter can change its type at runtime, in which case a different range could be
35-
/// applied.
35+
/// applied.
3636
/// * Introspection through service calls requires all the ranges to be reported to the user.
3737
#[derive(Clone, Debug, Default)]
3838
pub struct ParameterRanges {

rclrs/src/subscription.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,7 @@ where
272272
}
273273

274274
fn execute(&self) -> Result<(), RclrsError> {
275-
// Immediately evaluated closure, to handle SubscriptionTakeFailed
276-
// outside this match
277-
match (|| {
275+
let evaluate = || {
278276
match &mut *self.callback.lock().unwrap() {
279277
AnySubscriptionCallback::Regular(cb) => {
280278
let (msg, _) = self.take()?;
@@ -302,7 +300,11 @@ where
302300
}
303301
}
304302
Ok(())
305-
})() {
303+
};
304+
305+
// Immediately evaluated closure, to handle SubscriptionTakeFailed
306+
// outside this match
307+
match evaluate() {
306308
Err(RclrsError::RclError {
307309
code: RclReturnCode::SubscriptionTakeFailed,
308310
..

rclrs/src/subscription/message_info.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ use crate::rcl_bindings::*;
44

55
/// An identifier for a publisher in the local context.
66
///
7-
/// To quote the `rmw` documentation:
7+
/// To quote the [`rmw` documentation][1]:
88
///
99
/// > The identifier uniquely identifies the publisher for the local context, but
10-
/// it will not necessarily be the same identifier given in other contexts or processes
11-
/// for the same publisher.
12-
/// Therefore the identifier will uniquely identify the publisher within your application
13-
/// but may disagree about the identifier for that publisher when compared to another
14-
/// application.
15-
/// Even with this limitation, when combined with the publisher sequence number it can
16-
/// uniquely identify a message within your local context.
17-
/// Publisher GIDs generated by the RMW implementation could collide at some point, in which
18-
/// case it is not possible to distinguish which publisher sent the message.
19-
/// The details of how GIDs are generated are RMW implementation dependent.
20-
///
10+
/// > it will not necessarily be the same identifier given in other contexts or processes
11+
/// > for the same publisher.
12+
/// > Therefore the identifier will uniquely identify the publisher within your application
13+
/// > but may disagree about the identifier for that publisher when compared to another
14+
/// > application.
15+
/// > Even with this limitation, when combined with the publisher sequence number it can
16+
/// > uniquely identify a message within your local context.
17+
/// > Publisher GIDs generated by the RMW implementation could collide at some point, in which
18+
/// > case it is not possible to distinguish which publisher sent the message.
19+
/// > The details of how GIDs are generated are RMW implementation dependent.
20+
/// >
2121
/// > It is possible the the RMW implementation needs to reuse a publisher GID,
22-
/// due to running out of unique identifiers or some other constraint, in which case
23-
/// the RMW implementation may document what happens in that case, but that
24-
/// behavior is not defined here.
25-
/// However, this should be avoided, if at all possible, by the RMW implementation,
26-
/// and should be unlikely to happen in practice.
22+
/// > due to running out of unique identifiers or some other constraint, in which case
23+
/// > the RMW implementation may document what happens in that case, but that
24+
/// > behavior is not defined here.
25+
/// > However, this should be avoided, if at all possible, by the RMW implementation,
26+
/// > and should be unlikely to happen in practice.
27+
///
28+
/// [1]: https://docs.ros.org/en/rolling/p/rmw/generated/structrmw__message__info__s.html#_CPPv4N18rmw_message_info_s13publisher_gidE
2729
#[derive(Clone, Debug, PartialEq, Eq)]
2830
pub struct PublisherGid {
2931
/// Bytes identifying a publisher in the RMW implementation.

rclrs/src/wait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl WaitSet {
329329
///
330330
/// - Passing a wait set with no wait-able items in it will return an error.
331331
/// - The timeout must not be so large so as to overflow an `i64` with its nanosecond
332-
/// representation, or an error will occur.
332+
/// representation, or an error will occur.
333333
///
334334
/// This list is not comprehensive, since further errors may occur in the `rmw` or `rcl` layers.
335335
///

0 commit comments

Comments
 (0)