Skip to content

Commit 5bfe921

Browse files
committed
Add runtime trait to get the UUID from a goal request
C++ uses duck typing for this, knowing that for any `Action`, the type `Action::Impl::SendGoalService::Request` will always have a `goal_id` field of type `unique_identifier_msgs::msg::UUID` without having to prove this to the compiler. Rust's generics are more strict, requiring that this be proven using type bounds. The `Request` type is also action-specific as it contains a `goal` field containing the `Goal` message type of the action. We therefore cannot enforce that all `Request`s are a specific type in `rclrs`. This seems most easily represented using associated type bounds on the `SendGoalService` associated type within `ActionImpl`. To avoid introducing to `rosidl_runtime_rs` a circular dependency on message packages like `unique_identifier_msgs`, the `ExtractUuid` trait only operates on a byte array rather than a more nicely typed `UUID` message type. I'll likely revisit this as we introduce more similar bounds on the generated types.
1 parent a6b616b commit 5bfe921

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

rosidl_runtime_rs/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ mod string;
99
pub use string::{BoundedString, BoundedWString, String, StringExceedsBoundsError, WString};
1010

1111
mod traits;
12-
pub use traits::{Action, Message, RmwMessage, SequenceAlloc, Service};
12+
pub use traits::{Action, ActionImpl, ExtractUuid, Message, RmwMessage, SequenceAlloc, Service};

rosidl_runtime_rs/src/traits.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,19 @@ pub trait ActionImpl: 'static {
188188
type FeedbackMessage: Message;
189189

190190
/// The send_goal service associated with this action.
191-
type SendGoalService: Service;
191+
type SendGoalService: Service<Request: Message<RmwMsg: ExtractUuid>>;
192192

193193
/// The cancel_goal service associated with this action.
194194
type CancelGoalService: Service;
195195

196196
/// The get_result service associated with this action.
197197
type GetResultService: Service;
198198
}
199+
200+
/// Trait for types containing a special UUID field.
201+
///
202+
/// User code never needs to implement this trait, nor call its method.
203+
pub trait ExtractUuid: 'static {
204+
/// Copies the UUID field from `self` into the provided buffer.
205+
fn extract_uuid(&self, bytes: &mut [u8; 16]);
206+
}

0 commit comments

Comments
 (0)