Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,21 @@ list(APPEND _generated_common_rs_files
if(${_has_msg})
list(APPEND _generated_msg_rs_files
"${_output_path}/rust/src/msg.rs"
"${_output_path}/rust/src/msg/rmw.rs"
)
endif()

if(${_has_srv})
list(APPEND _generated_srv_rs_files
"${_output_path}/rust/src/srv.rs"
"${_output_path}/rust/src/srv/rmw.rs"
)
endif()

if(${_has_action})
list(APPEND _generated_action_rs_files
"${_output_path}/rust/src/action.rs"
"${_output_path}/rust/src/action/rmw.rs"
)
endif()

Expand All @@ -90,12 +93,15 @@ set(target_dependencies
"${rosidl_generator_rs_BIN}"
${rosidl_generator_rs_GENERATOR_FILES}
"${rosidl_generator_rs_TEMPLATE_DIR}/action.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg_rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/action/rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv_rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg/rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv/rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/templates/msg_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/templates/msg_rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/templates/srv_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/templates/srv_rmw.rs.em"
${rosidl_generate_interfaces_ABS_IDL_FILES}
${_idl_files}
${_dependency_files})
Expand Down
5 changes: 5 additions & 0 deletions rosidl_generator_rs/resource/Cargo.toml.em
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
rosidl_runtime_rs = "0.5"
serde = { version = "1", optional = true, features = ["derive"] }
serde-big-array = { version = "0.5.1", optional = true }

# ROS Dependencies
@[for dep in dependency_packages]@
@(dep) = "*"
@[end for]@
Expand All @@ -18,3 +20,6 @@ for dep in dependency_packages:
serde_features.append("{}/serde".format(dep))
}@
serde = @(serde_features)

[package.metadata.rclrs]
reexport = true
Comment on lines +24 to +25
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additional metadata I am exporting.

92 changes: 34 additions & 58 deletions rosidl_generator_rs/resource/action.rs.em
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,28 @@ for subfolder, action in action_specs:
action_srv_specs.append((subfolder, action.get_result_service))
}@

pub mod rmw {
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
@{
TEMPLATE(
'msg_rmw.rs.em',
package_name=package_name, interface_path=interface_path,
msg_specs=action_msg_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)

TEMPLATE(
'srv_rmw.rs.em',
package_name=package_name, interface_path=interface_path,
srv_specs=action_srv_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)
}@
} // mod rmw

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

@{
TEMPLATE(
'msg_idiomatic.rs.em',
'templates/msg_idiomatic.rs.em',
package_name=package_name, interface_path=interface_path,
msg_specs=action_msg_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
get_rs_name=get_rs_name,
get_rs_type=make_get_rs_type(True),
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)
}@

@{
TEMPLATE(
'srv_idiomatic.rs.em',
'templates/srv_idiomatic.rs.em',
package_name=package_name, interface_path=interface_path,
srv_specs=action_srv_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
get_rs_name=get_rs_name,
get_rs_type=make_get_rs_type(True),
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)
}@

Expand All @@ -90,15 +66,15 @@ pub struct @(type_name);

impl rosidl_runtime_rs::Action for @(type_name) {
// --- Associated types for client library users ---
type Goal = crate::@(subfolder)::@(type_name)@(ACTION_GOAL_SUFFIX);
type Result = crate::@(subfolder)::@(type_name)@(ACTION_RESULT_SUFFIX);
type Feedback = crate::@(subfolder)::@(type_name)@(ACTION_FEEDBACK_SUFFIX);
type Goal = @(type_name)@(ACTION_GOAL_SUFFIX);
type Result = @(type_name)@(ACTION_RESULT_SUFFIX);
type Feedback = @(type_name)@(ACTION_FEEDBACK_SUFFIX);

// --- Associated types for client library implementation ---
type FeedbackMessage = crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX);
type SendGoalService = crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX);
type FeedbackMessage = super::@(subfolder)::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX);
type SendGoalService = super::@(subfolder)::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX);
type CancelGoalService = action_msgs::srv::rmw::CancelGoal;
type GetResultService = crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX);
type GetResultService = super::@(subfolder)::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX);
Comment on lines +74 to +77
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of the changes look like this, simply replacing crate:: with super::. However, when we referenced external to this module types, (i.e. action_msgs::srv::rmw::CancelGoal) we will need to depend on another mechanism such as a using statement or pulling it in as a separate crate to resolve the module path.


// --- Methods for client library implementation ---
fn get_type_support() -> *const std::ffi::c_void {
Expand All @@ -108,28 +84,28 @@ impl rosidl_runtime_rs::Action for @(type_name) {

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) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
goal: super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SUFFIX),
) -> super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
goal,
}
}

fn split_goal_request(
request: crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX),
request: super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX),
) -> (
[u8; 16],
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SUFFIX),
super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SUFFIX),
) {
(request.goal_id.uuid, request.goal)
}

fn create_goal_response(
accepted: bool,
stamp: (i32, u32),
) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
) -> super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
accepted,
stamp: builtin_interfaces::msg::rmw::Time {
sec: stamp.0,
Expand All @@ -139,65 +115,65 @@ impl rosidl_runtime_rs::Action for @(type_name) {
}

fn get_goal_response_accepted(
response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX),
response: &super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX),
) -> bool {
response.accepted
}

fn get_goal_response_stamp(
response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX),
response: &super::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX),
) -> (i32, u32) {
(response.stamp.sec, response.stamp.nanosec)
}

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) {
let mut message = crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)::default();
feedback: super::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX),
) -> super::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX) {
let mut message = super::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)::default();
message.goal_id.uuid = *goal_id;
message.feedback = feedback;
message
}

fn split_feedback_message(
feedback: crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX),
feedback: super::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX),
) -> (
[u8; 16],
crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX),
super::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX),
) {
(feedback.goal_id.uuid, feedback.feedback)
}

fn create_result_request(
goal_id: &[u8; 16],
) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
) -> super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
}
}

fn get_result_request_uuid(
request: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX),
request: &super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX),
) -> &[u8; 16] {
&request.goal_id.uuid
}

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) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
result: super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX),
) -> super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
status,
result,
}
}

fn split_result_response(
response: crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)
response: super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)
) -> (
i8,
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX),
super::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX),
) {
(response.status, response.result)
}
Expand Down
49 changes: 49 additions & 0 deletions rosidl_generator_rs/resource/action/rmw.rs.em
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@{
from rosidl_parser.definition import (
ACTION_FEEDBACK_MESSAGE_SUFFIX,
ACTION_FEEDBACK_SUFFIX,
ACTION_GOAL_SERVICE_SUFFIX,
ACTION_GOAL_SUFFIX,
ACTION_RESULT_SERVICE_SUFFIX,
ACTION_RESULT_SUFFIX,
SERVICE_REQUEST_MESSAGE_SUFFIX,
SERVICE_RESPONSE_MESSAGE_SUFFIX,
)

action_msg_specs = []

for subfolder, action in action_specs:
action_msg_specs.append((subfolder, action.goal))
action_msg_specs.append((subfolder, action.result))
action_msg_specs.append((subfolder, action.feedback))
action_msg_specs.append((subfolder, action.feedback_message))

action_srv_specs = []

for subfolder, action in action_specs:
action_srv_specs.append((subfolder, action.send_goal_service))
action_srv_specs.append((subfolder, action.get_result_service))
}@

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

@{
TEMPLATE(
'../templates/msg_rmw.rs.em',
package_name=package_name, interface_path=interface_path,
msg_specs=action_msg_specs,
get_rs_name=get_rs_name,
get_rs_type=make_get_rs_type(False),
pre_field_serde=pre_field_serde,
constant_value_to_rs=constant_value_to_rs)

TEMPLATE(
'../templates/srv_rmw.rs.em',
package_name=package_name, interface_path=interface_path,
srv_specs=action_srv_specs,
get_rs_name=get_rs_name,
get_rs_type=make_get_rs_type(False),
pre_field_serde=pre_field_serde,
constant_value_to_rs=constant_value_to_rs)
}@
14 changes: 7 additions & 7 deletions rosidl_generator_rs/resource/build.rs.em
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::path::Path;
// use std::path::Path;

fn main() {
let lib_dir = Path::new("../../../lib")
.canonicalize()
.expect("Could not find '../../../lib'");
// This allows building Rust packages that depend on message crates without
// sourcing the install directory first.
println!("cargo:rustc-link-search={}", lib_dir.display());
// let lib_dir = Path::new("../../../lib")
// .canonicalize()
// .expect("Could not find '../../../lib'");
// // This allows building Rust packages that depend on message crates without
// // sourcing the install directory first.
// println!("cargo:rustc-link-search={}", lib_dir.display());
}
21 changes: 18 additions & 3 deletions rosidl_generator_rs/resource/lib.rs.em
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still ultimately want this structure, but a crate that wishes to re-export any of these symbols will need to arbitrarily add private use statements for any external modules. Consider something like this

pub mod builtin_interfaces { ... };

pub mod std_msgs {
  pub mod msg {
    use crate::builtin_interfaces;
    
    include!("path/to/generated/code");
    
    pub mod rmw {
      use crate::builtin_interfaces;
      
      include!("path/to/generated/rmw/code");
    }
  }
}

We need to create this rmw module in the generated crates lib.rs file rather than within these generated .rs files directly. This turned out to be more complicated than I bargained for. This was the simplest way I found to get this to export where relative symbols were looked up correctly in both a single crate or a re-export build.

Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,28 @@
#![allow(clippy::upper_case_acronyms)]

@[if len(msg_specs) > 0]@
pub mod msg;
#[path = "msg.rs"]
mod msg_idiomatic;
pub mod msg {
pub use super::msg_idiomatic::*;
pub mod rmw;
}
@[end if]@

@[if len(srv_specs) > 0]@
pub mod srv;
#[path = "srv.rs"]
mod srv_idiomatic;
pub mod srv {
pub use super::srv_idiomatic::*;
pub mod rmw;
}
@[end if]@

@[if len(action_specs) > 0]@
pub mod action;
#[path = "action.rs"]
mod action_idiomatic;
pub mod action {
pub use super::action_idiomatic::*;
pub mod rmw;
}
@[end if]@
21 changes: 3 additions & 18 deletions rosidl_generator_rs/resource/msg.rs.em
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
pub mod rmw {
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
@{
TEMPLATE(
'msg_rmw.rs.em',
package_name=package_name, interface_path=interface_path,
msg_specs=msg_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)
}@
} // mod rmw

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

@{
TEMPLATE(
'msg_idiomatic.rs.em',
'templates/msg_idiomatic.rs.em',
package_name=package_name, interface_path=interface_path,
msg_specs=msg_specs,
get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type,
get_rs_name=get_rs_name,
get_rs_type=make_get_rs_type(True),
pre_field_serde=pre_field_serde,
get_idiomatic_rs_type=get_idiomatic_rs_type,
constant_value_to_rs=constant_value_to_rs)
}@
Loading