Skip to content

Commit c5bd258

Browse files
committed
Implement client-side trait methods for action messages
This adds methods to ActionImpl for creating and accessing action-specific message types. These are needed by the rclrs ActionClient to generically read and write RMW messages. Due to issues with qualified paths in certain places (rust-lang/rust#86935), the generator now refers directly to its service and message types rather than going through associated types of the various traits. This also makes the generated code a little easier to read, with the trait method signatures from rosidl_runtime_rs still enforcing type-safety.
1 parent 7a39794 commit c5bd258

File tree

2 files changed

+85
-16
lines changed

2 files changed

+85
-16
lines changed

rosidl_generator_rs/resource/action.rs.em

+56-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ from rosidl_parser.definition import (
66
ACTION_GOAL_SUFFIX,
77
ACTION_RESULT_SERVICE_SUFFIX,
88
ACTION_RESULT_SUFFIX,
9+
SERVICE_REQUEST_MESSAGE_SUFFIX,
10+
SERVICE_RESPONSE_MESSAGE_SUFFIX,
911
)
1012

1113
action_msg_specs = []
@@ -100,31 +102,74 @@ impl rosidl_runtime_rs::ActionImpl for @(type_name) {
100102
type CancelGoalService = action_msgs::srv::rmw::CancelGoal;
101103
type GetResultService = crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX);
102104

103-
fn get_goal_request_uuid(request: &<<Self::SendGoalService as rosidl_runtime_rs::Service>::Request as rosidl_runtime_rs::Message>::RmwMsg) -> [u8; 16] {
104-
request.goal_id.uuid
105+
fn create_goal_request(goal_id: &[u8; 16], goal: crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
106+
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
107+
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
108+
goal,
109+
}
110+
}
111+
112+
fn get_goal_request_uuid(request: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX)) -> &[u8; 16] {
113+
&request.goal_id.uuid
114+
}
115+
116+
fn create_goal_response(accepted: bool, stamp: (i32, u32)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
117+
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
118+
accepted,
119+
stamp: builtin_interfaces::msg::rmw::Time {
120+
sec: stamp.0,
121+
nanosec: stamp.1,
122+
},
123+
}
124+
}
125+
126+
fn get_goal_response_accepted(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> bool {
127+
response.accepted
105128
}
106129

107-
fn set_goal_response_accepted(response: &mut <<Self::SendGoalService as rosidl_runtime_rs::Service>::Response as rosidl_runtime_rs::Message>::RmwMsg, accepted: bool) {
108-
response.accepted = accepted;
130+
fn get_goal_response_stamp(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> (i32, u32) {
131+
(response.stamp.sec, response.stamp.nanosec)
109132
}
110133

111-
fn create_feedback_message(goal_id: &[u8; 16], feedback: &<<Self as rosidl_runtime_rs::Action>::Feedback as rosidl_runtime_rs::Message>::RmwMsg) -> <Self::FeedbackMessage as rosidl_runtime_rs::Message>::RmwMsg {
112-
let mut message = <Self::FeedbackMessage as rosidl_runtime_rs::Message>::RmwMsg::default();
134+
fn create_feedback_message(goal_id: &[u8; 16], feedback: crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX) {
135+
let mut message = crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)::default();
113136
message.goal_id.uuid = *goal_id;
114-
message.feedback = feedback.clone();
137+
message.feedback = feedback;
115138
message
116139
}
117140

118-
fn get_result_request_uuid(request: &<<Self::GetResultService as rosidl_runtime_rs::Service>::Request as rosidl_runtime_rs::Message>::RmwMsg) -> [u8; 16] {
119-
request.goal_id.uuid
141+
fn get_feedback_message_uuid(feedback: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)) -> &[u8; 16] {
142+
&feedback.goal_id.uuid
143+
}
144+
145+
fn get_feedback_message_feedback(feedback: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)) -> &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX) {
146+
&feedback.feedback
120147
}
121148

122-
fn create_result_response(status: i8, result: <<Self as Action>::Result as Message>::RmwMsg) -> <<Self::GetResultService as Service>::Response as Message>::RmwMsg {
123-
<<Self::GetResultService as rosidl_runtime_rs::Service>::Response as rosidl_runtime_rs::Message>::RmwMsg {
149+
fn create_result_request(goal_id: &[u8; 16]) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
150+
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
151+
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
152+
}
153+
}
154+
155+
fn get_result_request_uuid(request: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX)) -> &[u8; 16] {
156+
&request.goal_id.uuid
157+
}
158+
159+
fn create_result_response(status: i8, result: crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
160+
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
124161
status,
125162
result,
126163
}
127164
}
165+
166+
fn get_result_response_result(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX) {
167+
&response.result
168+
}
169+
170+
fn get_result_response_status(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> i8 {
171+
response.status
172+
}
128173
}
129174

130175
@[end for]

rosidl_runtime_rs/src/traits.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -196,18 +196,42 @@ pub trait ActionImpl: 'static + Action {
196196
/// The get_result service associated with this action.
197197
type GetResultService: Service;
198198

199+
/// Create a goal request message with the given UUID and goal.
200+
fn create_goal_request(goal_id: &[u8; 16], goal: <<Self as Action>::Goal as Message>::RmwMsg) -> <<Self::SendGoalService as Service>::Request as Message>::RmwMsg;
201+
199202
/// Get the UUID of a goal request.
200-
fn get_goal_request_uuid(request: &<<Self::SendGoalService as Service>::Request as Message>::RmwMsg) -> [u8; 16];
203+
fn get_goal_request_uuid(request: &<<Self::SendGoalService as Service>::Request as Message>::RmwMsg) -> &[u8; 16];
204+
205+
/// Create a goal response message with the given acceptance and timestamp.
206+
fn create_goal_response(accepted: bool, stamp: (i32, u32)) -> <<Self::SendGoalService as Service>::Response as Message>::RmwMsg;
201207

202-
/// Sets the `accepted` field of a goal response.
203-
fn set_goal_response_accepted(response: &mut <<Self::SendGoalService as Service>::Response as Message>::RmwMsg, accepted: bool);
208+
/// Get the `accepted` field of a goal response.
209+
fn get_goal_response_accepted(response: &<<Self::SendGoalService as Service>::Response as Message>::RmwMsg) -> bool;
210+
211+
/// Get the `stamp` field of a goal response.
212+
fn get_goal_response_stamp(response: &<<Self::SendGoalService as Service>::Response as Message>::RmwMsg) -> (i32, u32);
204213

205214
/// Create a feedback message with the given goal ID and contents.
206-
fn create_feedback_message(goal_id: &[u8; 16], feedback: &<<Self as Action>::Feedback as Message>::RmwMsg) -> <Self::FeedbackMessage as Message>::RmwMsg;
215+
fn create_feedback_message(goal_id: &[u8; 16], feedback: <<Self as Action>::Feedback as Message>::RmwMsg) -> <Self::FeedbackMessage as Message>::RmwMsg;
216+
217+
/// Get the UUID of a feedback message.
218+
fn get_feedback_message_uuid(feedback: &<Self::FeedbackMessage as Message>::RmwMsg) -> &[u8; 16];
219+
220+
/// Get the feedback of a feedback message.
221+
fn get_feedback_message_feedback(feedback: &<Self::FeedbackMessage as Message>::RmwMsg) -> &<<Self as Action>::Feedback as Message>::RmwMsg;
222+
223+
/// Create a result request message with the given goal ID.
224+
fn create_result_request(goal_id: &[u8; 16]) -> <<Self::GetResultService as Service>::Request as Message>::RmwMsg;
207225

208226
/// Get the UUID of a result request.
209-
fn get_result_request_uuid(request: &<<Self::GetResultService as Service>::Request as Message>::RmwMsg) -> [u8; 16];
227+
fn get_result_request_uuid(request: &<<Self::GetResultService as Service>::Request as Message>::RmwMsg) -> &[u8; 16];
210228

211229
/// Create a result response message with the given status and contents.
212230
fn create_result_response(status: i8, result: <<Self as Action>::Result as Message>::RmwMsg) -> <<Self::GetResultService as Service>::Response as Message>::RmwMsg;
231+
232+
/// Get the result of a result response.
233+
fn get_result_response_result(response: &<<Self::GetResultService as Service>::Response as Message>::RmwMsg) -> &<<Self as Action>::Result as Message>::RmwMsg;
234+
235+
/// Get the status of a result response.
236+
fn get_result_response_status(response: &<<Self::GetResultService as Service>::Response as Message>::RmwMsg) -> i8;
213237
}

0 commit comments

Comments
 (0)