Conditional compilation and array improvements
This commit is contained in:
parent
37991a2363
commit
5d30028e37
2
build.rs
2
build.rs
|
|
@ -34,6 +34,8 @@ fn main() {
|
|||
|
||||
for msg in msgs {
|
||||
codegen.push_str(&generate_rust_msg(module, prefix, msg));
|
||||
|
||||
println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg);
|
||||
}
|
||||
|
||||
codegen.push_str(" }\n");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Read};
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
#![allow(non_snake_case)]
|
||||
#![allow(improper_ctypes)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
#![allow(clippy::if_same_then_else)]
|
||||
include!(concat!(env!("OUT_DIR"), "/msg_bindings.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/introspection_functions.rs"));
|
||||
|
||||
|
|
@ -159,7 +157,38 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
let field_name = field_name(CStr::from_ptr(member.name_).to_str().unwrap());
|
||||
let rust_field_type = field_type(member.type_id_);
|
||||
|
||||
if member.is_array_ {
|
||||
if member.is_array_ && member.array_size_ > 0 && !member.is_upper_bound_ {
|
||||
// these are plain arrays
|
||||
let ss = format!("// is_upper_bound_: {}\n", member.is_upper_bound_);
|
||||
from_native.push_str(&ss);
|
||||
let ss = format!("// member.array_size_ : {}\n", member.array_size_);
|
||||
from_native.push_str(&ss);
|
||||
if rust_field_type == "message" {
|
||||
let (module, prefix, name, _, _) = introspection(member.members_);
|
||||
from_native.push_str(&format!("{field_name} : {{\n", field_name = field_name));
|
||||
from_native.push_str(&format!(
|
||||
"let mut temp = Vec::with_capacity(msg.{field_name}.len());\n",
|
||||
field_name = field_name
|
||||
));
|
||||
from_native.push_str(&format!("for s in &msg.{field_name} {{ temp.push({module}::{prefix}::{msgname}::from_native(s)); }}\n", field_name = field_name, module = module, prefix=prefix, msgname = name));
|
||||
from_native.push_str("temp },\n");
|
||||
} else if rust_field_type == "std::string::String" {
|
||||
from_native.push_str(&format!(
|
||||
"{field_name}: msg.{field_name}.iter().map(|s|s.to_str().to_owned()).collect(),\n",
|
||||
field_name = field_name
|
||||
));
|
||||
} else {
|
||||
from_native.push_str(&format!(
|
||||
"{field_name}: msg.{field_name}.to_vec(),\n",
|
||||
field_name = field_name
|
||||
));
|
||||
}
|
||||
} else if member.is_array_ && (member.array_size_ == 0 || member.is_upper_bound_) {
|
||||
// these are __Sequence:s
|
||||
let ss = format!("// is_upper_bound_: {}\n", member.is_upper_bound_);
|
||||
from_native.push_str(&ss);
|
||||
let ss = format!("// member.array_size_ : {}\n", member.array_size_);
|
||||
from_native.push_str(&ss);
|
||||
if rust_field_type == "message" {
|
||||
let (module, prefix, name, _, _) = introspection(member.members_);
|
||||
from_native.push_str(&format!("{field_name} : {{\n", field_name = field_name));
|
||||
|
|
@ -171,19 +200,10 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
from_native.push_str(&format!("for s in slice {{ temp.push({module}::{prefix}::{msgname}::from_native(s)); }}\n", module = module, prefix=prefix, msgname = name));
|
||||
from_native.push_str("temp },\n");
|
||||
} else {
|
||||
if member.array_size_ > 0 {
|
||||
// fixed size array, copy elements (happens to be the same now that we are using vectors...)
|
||||
from_native.push_str(&format!(
|
||||
"{field_name}: msg.{field_name}.to_vec(),\n",
|
||||
field_name = field_name
|
||||
));
|
||||
} else {
|
||||
let x = 1;
|
||||
from_native.push_str(&format!(
|
||||
"{field_name}: msg.{field_name}.to_vec(),\n",
|
||||
field_name = field_name
|
||||
));
|
||||
}
|
||||
from_native.push_str(&format!(
|
||||
"{field_name}: msg.{field_name}.to_vec(),\n",
|
||||
field_name = field_name
|
||||
));
|
||||
}
|
||||
} else if rust_field_type == "std::string::String" {
|
||||
from_native.push_str(&format!(
|
||||
|
|
@ -209,7 +229,21 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
let field_name = field_name(CStr::from_ptr((*member).name_).to_str().unwrap());
|
||||
let rust_field_type = field_type(member.type_id_);
|
||||
|
||||
if member.is_array_ {
|
||||
if member.is_array_ && member.array_size_ > 0 && !member.is_upper_bound_ {
|
||||
// these are plain arrays
|
||||
// fixed size array, just copy but first check the size!
|
||||
copy_to_native.push_str(&format!("assert_eq!(self.{field_name}.len(), {array_size}, \"Field {{}} is fixed size of {{}}!\", \"{field_name}\", {array_size});\n", field_name = field_name, array_size = member.array_size_));
|
||||
if rust_field_type == "message" {
|
||||
copy_to_native.push_str(&format!("for (t,s) in msg.{field_name}.iter_mut().zip(&self.{field_name}) {{ s.copy_to_native(t);}}\n", field_name=field_name));
|
||||
}
|
||||
else if rust_field_type == "std::string::String" {
|
||||
copy_to_native.push_str(&format!("for (t,s) in msg.{field_name}.iter_mut().zip(&self.{field_name}) {{ t.assign(&s);}}\n", field_name=field_name));
|
||||
} else {
|
||||
copy_to_native.push_str(&format!("msg.{field_name}.copy_from_slice(&self.{field_name}[..{array_size}]);\n", field_name = field_name, array_size = member.array_size_));
|
||||
}
|
||||
}
|
||||
else if member.is_array_ && (member.array_size_ == 0 || member.is_upper_bound_) {
|
||||
// these are __Sequence:s
|
||||
if rust_field_type == "message" {
|
||||
let (_, _, _, c_struct, _) = introspection(member.members_);
|
||||
copy_to_native.push_str(&format!(
|
||||
|
|
@ -221,20 +255,14 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
copy_to_native.push_str(&format!("let slice = unsafe {{ std::slice::from_raw_parts_mut(msg.{field_name}.data, msg.{field_name}.size)}};\n",field_name = field_name));
|
||||
copy_to_native.push_str(&format!("for (t,s) in slice.iter_mut().zip(&self.{field_name}) {{ s.copy_to_native(t);}}\n", field_name=field_name));
|
||||
} else {
|
||||
if member.array_size_ > 0 && !member.is_upper_bound_ {
|
||||
// fixed size array, just copy but first check the size!
|
||||
copy_to_native.push_str(&format!("assert_eq!(self.{field_name}.len(), {array_size}, \"Field {{}} is fixed size of {{}}!\", \"{field_name}\", {array_size});\n", field_name = field_name, array_size = member.array_size_));
|
||||
copy_to_native.push_str(&format!("msg.{field_name}.copy_from_slice(&self.{field_name}[..{array_size}]);\n", field_name = field_name, array_size = member.array_size_));
|
||||
} else {
|
||||
if member.is_upper_bound_ {
|
||||
// extra assertion
|
||||
copy_to_native.push_str(&format!("assert!(self.{field_name}.len() <= {array_size}, \"Field {{}} is upper bounded by {{}}!\", \"{field_name}\", {array_size});\n", field_name = field_name, array_size = member.array_size_));
|
||||
}
|
||||
copy_to_native.push_str(&format!(
|
||||
"msg.{field_name}.update(&self.{field_name});\n",
|
||||
field_name = field_name
|
||||
));
|
||||
// extra assertion
|
||||
if member.is_upper_bound_ {
|
||||
copy_to_native.push_str(&format!("assert!(self.{field_name}.len() <= {array_size}, \"Field {{}} is upper bounded by {{}}!\", \"{field_name}\", {array_size});\n", field_name = field_name, array_size = member.array_size_));
|
||||
}
|
||||
copy_to_native.push_str(&format!(
|
||||
"msg.{field_name}.update(&self.{field_name});\n",
|
||||
field_name = field_name
|
||||
));
|
||||
}
|
||||
} else if rust_field_type == "std::string::String" {
|
||||
copy_to_native.push_str(&format!(
|
||||
|
|
@ -276,17 +304,29 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
copy_to_native = copy_to_native
|
||||
);
|
||||
|
||||
let impl_default = format!(
|
||||
"
|
||||
impl Default for {msgname} {{
|
||||
fn default() -> Self {{
|
||||
let msg_native = WrappedNativeMsg::<{msgname}>::new();
|
||||
{msgname}::from_native(&msg_native)
|
||||
}}
|
||||
}}
|
||||
", msgname = name);
|
||||
|
||||
let module_str = format!(
|
||||
"
|
||||
#[derive(Clone,Debug,Default,PartialEq,Serialize,Deserialize)]
|
||||
#[derive(Clone,Debug,PartialEq,Serialize,Deserialize)]
|
||||
pub struct {msgname} {{\n
|
||||
{fields}
|
||||
}}\n
|
||||
{typesupport}\n\n
|
||||
{typesupport}\n
|
||||
{default}\n\n
|
||||
",
|
||||
msgname = name,
|
||||
fields = fields,
|
||||
typesupport = typesupport
|
||||
typesupport = typesupport,
|
||||
default = impl_default
|
||||
);
|
||||
|
||||
module_str
|
||||
|
|
|
|||
|
|
@ -151,5 +151,3 @@ primitive_sequence!(rosidl_generator_c__uint32, u32);
|
|||
primitive_sequence!(rosidl_generator_c__int32, i32);
|
||||
primitive_sequence!(rosidl_generator_c__uint64, u64);
|
||||
primitive_sequence!(rosidl_generator_c__int64, i64);
|
||||
|
||||
|
||||
|
|
|
|||
42
src/lib.rs
42
src/lib.rs
|
|
@ -860,8 +860,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_untyped_json() -> () {
|
||||
use trajectory_msgs::msg::*;
|
||||
let mut msg: JointTrajectoryPoint = Default::default();
|
||||
let mut msg = trajectory_msgs::msg::JointTrajectoryPoint::default();
|
||||
msg.positions.push(39.0);
|
||||
msg.positions.push(34.0);
|
||||
let json = serde_json::to_value(msg.clone()).unwrap();
|
||||
|
|
@ -871,8 +870,45 @@ mod tests {
|
|||
let json2 = native.to_json().unwrap();
|
||||
assert_eq!(json, json2);
|
||||
|
||||
let msg2: JointTrajectoryPoint = serde_json::from_value(json2).unwrap();
|
||||
let msg2: trajectory_msgs::msg::JointTrajectoryPoint = serde_json::from_value(json2).unwrap();
|
||||
assert_eq!(msg, msg2);
|
||||
}
|
||||
|
||||
#[cfg(r2r__test_msgs__msg__Arrays)]
|
||||
#[test]
|
||||
fn test_test_msgs_array() -> () {
|
||||
let mut msg = test_msgs::msg::Arrays::default();
|
||||
println!("msg: {:?}", msg.string_values);
|
||||
msg.string_values = vec![
|
||||
"hej".to_string(), "hopp".to_string(), "stropp".to_string()
|
||||
];
|
||||
|
||||
let msg_native = WrappedNativeMsg::<test_msgs::msg::Arrays>::from(&msg);
|
||||
let msg2 = test_msgs::msg::Arrays::from_native(&msg_native);
|
||||
|
||||
assert_eq!(msg, msg2);
|
||||
}
|
||||
|
||||
#[cfg(r2r__test_msgs__msg__Arrays)]
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_test_msgs_array_too_few_elems() -> () {
|
||||
let mut msg = test_msgs::msg::Arrays::default();
|
||||
println!("msg: {:?}", msg.string_values);
|
||||
msg.string_values = vec![ "hej".to_string(), "hopp".to_string() ];
|
||||
let _msg_native = WrappedNativeMsg::<test_msgs::msg::Arrays>::from(&msg);
|
||||
}
|
||||
|
||||
#[cfg(r2r__test_msgs__msg__WStrings)]
|
||||
#[test]
|
||||
fn test_test_msgs_wstring() -> () {
|
||||
let mut msg = test_msgs::msg::WStrings::default();
|
||||
let rust_str = "ハローワールド";
|
||||
msg.wstring_value = rust_str.to_string();
|
||||
let native = WrappedNativeMsg::<test_msgs::msg::WStrings>::from(&msg);
|
||||
println!("msg: {:?}", msg);
|
||||
let msg2 = test_msgs::msg::WStrings::from_native(&native);
|
||||
assert_eq!(msg.wstring_value, msg2.wstring_value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue