From db34e81c37c91a75f13fd0cc3a2a005324ac9e5e Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Tue, 23 Apr 2024 17:55:23 +0200 Subject: [PATCH 1/9] Simplify parsing of `AMENT_PREFIX_PATH` This PR simplify how ROS2 messages are parsed using dora. It will parse all messages included in the `AMENT_PREFIX_PATH` folder that has a path in the following format: `/msg/.msg`. Similarly for services it will be parsed as: `/srv/.srv`. It does not requires `.idl` anymore nor does it needs to be in the `ament_index`. --- Cargo.lock | 1 + .../extensions/ros2-bridge/msg-gen/Cargo.toml | 1 + .../ros2-bridge/msg-gen/src/parser/package.rs | 217 ++++++++---------- 3 files changed, 96 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e7139270..9da2e4f4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2564,6 +2564,7 @@ name = "dora-ros2-bridge-msg-gen" version = "0.1.0" dependencies = [ "anyhow", + "glob", "heck 0.3.3", "nom", "proc-macro2", diff --git a/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml b/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml index 87d9ea250..7d778888e 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml +++ b/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml @@ -14,3 +14,4 @@ quote = "1.0" regex = "1" syn = "1.0" thiserror = "1.0" +glob = "0.3.1" diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index 12e7da5ce..390586f89 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -1,94 +1,108 @@ -use std::{ - fs::{self, File}, - io::{BufRead, BufReader}, - path::Path, -}; +use std::{collections::HashMap, path::Path}; -use anyhow::Result; +use anyhow::{Context, Result}; +use glob::glob; use super::{action::parse_action_file, message::parse_message_file, service::parse_service_file}; use crate::types::Package; -const ROSIDL_INTERFACES: &str = "share/ament_index/resource_index/rosidl_interfaces"; - -const NAMESPACES: &[&str] = &["msg", "srv", "action"]; - -fn parse_line(line: &str) -> Option<(&str, &str)> { - if !line.ends_with(".idl") { - return None; - } - for &namespace in NAMESPACES { - if line.starts_with(&format!("{}/", namespace)) { - let name = &line[namespace.len() + 1..line.len() - 4]; - return Some((namespace, name)); - } - } - println!("Unknown type: {:?}", line); - None -} - -fn get_ros_msgs_each_package>(root_dir: P) -> Result> { - let dir = root_dir.as_ref().join(ROSIDL_INTERFACES); - - let mut packages = Vec::new(); - - let paths = match fs::read_dir(dir) { - Ok(paths) => paths, - Err(_) => { - return Ok(packages); - } - }; - - for path in paths { - let path = path?.path(); - let file_name = path - .clone() - .file_name() - .unwrap() - .to_str() - .unwrap() - .to_string(); - // Hack - if file_name == "libstatistics_collector" { - continue; - } - - let mut package = Package::new(file_name.clone()); - for line in BufReader::new(File::open(path)?).lines() { - match parse_line(&line?) { - Some(("msg", v)) => { - let msg = parse_message_file( - &file_name, - root_dir - .as_ref() - .join(format!("share/{}/msg/{}.msg", file_name, v)), - )?; - package.messages.push(msg); +fn get_ros_msgs_each_package>(_root_dir: P) -> Result> { + let mut map: HashMap = HashMap::new(); + if let Ok(ament_prefix_path) = std::env::var("AMENT_PREFIX_PATH") { + let pattern = ament_prefix_path.clone() + "/**/msg/*.msg"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.messages.push(parse_message_file(&package, path.clone())?); + } + None => { + let mut p = Package::new(package.clone()); + p.messages.push(parse_message_file(&package, path.clone())?); + map.insert(package, p); + } + }; } - Some(("srv", v)) => { - let srv = parse_service_file( - &file_name, - root_dir - .as_ref() - .join(format!("share/{}/srv/{}.srv", file_name, v)), - )?; - package.services.push(srv); + Err(e) => eprintln!("{:?}", e), + } + } + let pattern = ament_prefix_path.clone() + "/**/srv/*.srv"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.services.push(parse_service_file(&package, path.clone())?); + } + None => { + let mut p = Package::new(package.clone()); + p.services.push(parse_service_file(&package, path.clone())?); + map.insert(package, p); + } + }; } - Some(("action", v)) => { - let action = parse_action_file( - &file_name, - root_dir - .as_ref() - .join(format!("share/{}/action/{}.action", file_name, v)), - )?; - package.actions.push(action); + Err(e) => eprintln!("{:?}", e), + } + } + let pattern = ament_prefix_path + "/**/action/*.action"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .clone() + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.actions.push( + parse_action_file(&package, path.clone()) + .context("could not parse action")?, + ); + } + None => { + let mut p = Package::new(package.clone()); + p.actions.push( + parse_action_file(&package, path.clone()) + .context("could not parse message")?, + ); + map.insert(package, p); + } + }; } - Some(_) => unreachable!(), - None => {} + Err(e) => eprintln!("{:?}", e), } } - packages.push(package); + debug_assert!( + map.len() > 0, + "it seens that no package was generated from your AMENT_PREFIX_PATH directory" + ); } + let packages = map.into_values().collect(); Ok(packages) } @@ -110,46 +124,3 @@ where Ok(packages) } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_line_msg() { - let result = parse_line("msg/TestHoge.idl").unwrap(); - - assert_eq!(result.0, "msg"); - assert_eq!(result.1, "TestHoge"); - } - - #[test] - fn parse_line_srv() { - let result = parse_line("srv/TestHoge.idl").unwrap(); - - assert_eq!(result.0, "srv"); - assert_eq!(result.1, "TestHoge"); - } - - #[test] - fn parse_line_action() { - let result = parse_line("action/TestHoge.idl").unwrap(); - - assert_eq!(result.0, "action"); - assert_eq!(result.1, "TestHoge"); - } - - #[test] - fn parse_line_wrong_namespace() { - assert!(parse_line("test/Test.msg").is_none()); - assert!(parse_line("test/Test.srv").is_none()); - assert!(parse_line("test/Test.action").is_none()); - } - - #[test] - fn parse_line_wrong_suffix() { - assert!(parse_line("msg/Test.test").is_none()); - assert!(parse_line("srv/Test.test").is_none()); - assert!(parse_line("action/Test.test").is_none()); - } -} From f94a810890ce1019743704a1bd060f7bca24e5ad Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Tue, 23 Apr 2024 18:21:36 +0200 Subject: [PATCH 2/9] Use `root_dir` for multi directory scenario --- .../ros2-bridge/msg-gen/src/parser/package.rs | 176 +++++++++--------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index 390586f89..f0889a6a7 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -6,102 +6,102 @@ use glob::glob; use super::{action::parse_action_file, message::parse_message_file, service::parse_service_file}; use crate::types::Package; -fn get_ros_msgs_each_package>(_root_dir: P) -> Result> { +fn get_ros_msgs_each_package>(root_dir: P) -> Result> { let mut map: HashMap = HashMap::new(); - if let Ok(ament_prefix_path) = std::env::var("AMENT_PREFIX_PATH") { - let pattern = ament_prefix_path.clone() + "/**/msg/*.msg"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.messages.push(parse_message_file(&package, path.clone())?); - } - None => { - let mut p = Package::new(package.clone()); - p.messages.push(parse_message_file(&package, path.clone())?); - map.insert(package, p); - } - }; - } - Err(e) => eprintln!("{:?}", e), + + let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/msg/*.msg"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.messages.push(parse_message_file(&package, path.clone())?); + } + None => { + let mut p = Package::new(package.clone()); + p.messages.push(parse_message_file(&package, path.clone())?); + map.insert(package, p); + } + }; } + Err(e) => eprintln!("{:?}", e), } - let pattern = ament_prefix_path.clone() + "/**/srv/*.srv"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.services.push(parse_service_file(&package, path.clone())?); - } - None => { - let mut p = Package::new(package.clone()); - p.services.push(parse_service_file(&package, path.clone())?); - map.insert(package, p); - } - }; - } - Err(e) => eprintln!("{:?}", e), + } + let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/srv/*.srv"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.services.push(parse_service_file(&package, path.clone())?); + } + None => { + let mut p = Package::new(package.clone()); + p.services.push(parse_service_file(&package, path.clone())?); + map.insert(package, p); + } + }; } + Err(e) => eprintln!("{:?}", e), } - let pattern = ament_prefix_path + "/**/action/*.action"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .clone() - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.actions.push( - parse_action_file(&package, path.clone()) - .context("could not parse action")?, - ); - } - None => { - let mut p = Package::new(package.clone()); - p.actions.push( - parse_action_file(&package, path.clone()) - .context("could not parse message")?, - ); - map.insert(package, p); - } - }; - } - Err(e) => eprintln!("{:?}", e), + } + let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/action/*.action"; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let package = path + .clone() + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + match map.get_mut(&package) { + Some(p) => { + p.actions.push( + parse_action_file(&package, path.clone()) + .context("could not parse action")?, + ); + } + None => { + let mut p = Package::new(package.clone()); + p.actions.push( + parse_action_file(&package, path.clone()) + .context("could not parse message")?, + ); + map.insert(package, p); + } + }; } + Err(e) => eprintln!("{:?}", e), } - debug_assert!( - map.len() > 0, - "it seens that no package was generated from your AMENT_PREFIX_PATH directory" - ); } + debug_assert!( + map.len() > 0, + "it seens that no package was generated from your AMENT_PREFIX_PATH directory" + ); + let packages = map.into_values().collect(); Ok(packages) } From a09a50d4811e65af494d95a3b081a9cd4d3b1273 Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Tue, 23 Apr 2024 19:26:40 +0200 Subject: [PATCH 3/9] Added warning and fix for cases with 2 messages definition of the same (package, message) Fix CI by ficing widestring proc_macro, fixing clippy, adding CI flag fix CI with minor changes --- Cargo.lock | 1 + .../extensions/ros2-bridge/msg-gen/Cargo.toml | 1 + .../ros2-bridge/msg-gen/src/parser/package.rs | 160 ++++++++---------- .../msg-gen/src/types/primitives.rs | 2 +- 4 files changed, 78 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9da2e4f4c..269ca9d1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2572,6 +2572,7 @@ dependencies = [ "regex", "syn 1.0.109", "thiserror", + "tracing", ] [[package]] diff --git a/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml b/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml index 7d778888e..2bd92348b 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml +++ b/libraries/extensions/ros2-bridge/msg-gen/Cargo.toml @@ -15,3 +15,4 @@ regex = "1" syn = "1.0" thiserror = "1.0" glob = "0.3.1" +tracing = "0.1.33" diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index f0889a6a7..f05a93370 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, path::Path}; use anyhow::{Context, Result}; use glob::glob; +use tracing::warn; use super::{action::parse_action_file, message::parse_message_file, service::parse_service_file}; use crate::types::Package; @@ -9,96 +10,85 @@ use crate::types::Package; fn get_ros_msgs_each_package>(root_dir: P) -> Result> { let mut map: HashMap = HashMap::new(); - let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/msg/*.msg"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.messages.push(parse_message_file(&package, path.clone())?); - } - None => { - let mut p = Package::new(package.clone()); - p.messages.push(parse_message_file(&package, path.clone())?); - map.insert(package, p); - } - }; - } - Err(e) => eprintln!("{:?}", e), - } - } - let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/srv/*.srv"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.services.push(parse_service_file(&package, path.clone())?); - } - None => { - let mut p = Package::new(package.clone()); - p.services.push(parse_service_file(&package, path.clone())?); - map.insert(package, p); - } - }; - } - Err(e) => eprintln!("{:?}", e), - } - } - let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/action/*.action"; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let package = path - .clone() - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); - match map.get_mut(&package) { - Some(p) => { - p.actions.push( - parse_action_file(&package, path.clone()) - .context("could not parse action")?, - ); - } - None => { - let mut p = Package::new(package.clone()); - p.actions.push( - parse_action_file(&package, path.clone()) - .context("could not parse message")?, - ); - map.insert(package, p); + let ros_formats = vec!["msg", "srv", "action"]; + for ros_format in ros_formats { + let pattern = root_dir.as_ref().to_string_lossy().to_string() + + "/**/" + + ros_format + + "/*." + + ros_format; + let mut visited_files = vec![]; + for entry in glob(&pattern).expect("Failed to read glob pattern") { + match entry { + Ok(path) => { + let file_name = path + .clone() + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string(); + + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); + + // Hack + if file_name == "libstatistics_collector" { + continue; + } else if visited_files.contains(&(package.clone(), file_name.clone())) { + warn!( + "found two versions of package: {:?}, message: {:?}. will skip the one in: {:#?}", + package, file_name, path + ); + continue; + } else { + visited_files.push((package.clone(), file_name.clone())); } - }; + + match map.get_mut(&package) { + Some(p) => match ros_format { + "msg" => { + p.messages.push(parse_message_file(&package, path.clone())?); + } + "srv" => { + p.services.push(parse_service_file(&package, path.clone())?); + } + "action" => { + p.actions.push(parse_action_file(&package, path.clone())?); + } + _ => todo!(), + }, + None => { + let mut p = Package::new(package.clone()); + match ros_format { + "msg" => { + p.messages.push(parse_message_file(&package, path.clone())?); + } + "srv" => { + p.services.push(parse_service_file(&package, path.clone())?); + } + "action" => { + p.actions.push(parse_action_file(&package, path.clone())?); + } + _ => todo!(), + } + map.insert(package, p); + } + }; + } + Err(e) => eprintln!("{:?}", e), } - Err(e) => eprintln!("{:?}", e), } } debug_assert!( - map.len() > 0, + !map.is_empty(), "it seens that no package was generated from your AMENT_PREFIX_PATH directory" ); diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/types/primitives.rs b/libraries/extensions/ros2-bridge/msg-gen/src/types/primitives.rs index 56d001498..c6da532c3 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/types/primitives.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/types/primitives.rs @@ -241,7 +241,7 @@ impl GenericString { // TODO: Assertion let value = Literal::string(value); if self.is_wide() { - quote! { ::widestring::U16String::from_str(#value) } + quote! { ffi::U16String::from_str(#value) } } else { quote! { ::std::string::String::from(#value) } } From f3b407ca7f755609ad9d1752c4f07d2c369b69dd Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Fri, 26 Apr 2024 16:25:54 +0200 Subject: [PATCH 4/9] Return emptuy package vec if AMENT_PREFIX_PATH points to '' Fix https://github.com/dora-rs/dora/issues/481#issuecomment-2075193358 --- .../extensions/ros2-bridge/msg-gen/src/parser/package.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index f05a93370..781ac65a3 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, path::Path}; +use std::{collections::HashMap, io::Empty, path::Path}; use anyhow::{Context, Result}; use glob::glob; @@ -11,6 +11,13 @@ fn get_ros_msgs_each_package>(root_dir: P) -> Result let mut map: HashMap = HashMap::new(); let ros_formats = vec!["msg", "srv", "action"]; + + if root_dir.as_ref() != Path::new("") { + let empty_vec: Vec = vec![]; + warn!("AMENT_PREFIX_PATH pointed to ''"); + return Ok(empty_vec); + } + for ros_format in ros_formats { let pattern = root_dir.as_ref().to_string_lossy().to_string() + "/**/" From ab28403f5fc919159143f6d948ac14b61449e9d2 Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Mon, 29 Apr 2024 17:44:08 +0200 Subject: [PATCH 5/9] Fix `AMENT_PREFIX_PATH` --- .../extensions/ros2-bridge/msg-gen/src/parser/package.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index 781ac65a3..dd9104e1c 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, io::Empty, path::Path}; +use std::{collections::HashMap, path::Path}; use anyhow::{Context, Result}; use glob::glob; @@ -12,7 +12,8 @@ fn get_ros_msgs_each_package>(root_dir: P) -> Result let ros_formats = vec!["msg", "srv", "action"]; - if root_dir.as_ref() != Path::new("") { + // Return empty vector if root_dir is empty + if root_dir.as_ref() == Path::new("") { let empty_vec: Vec = vec![]; warn!("AMENT_PREFIX_PATH pointed to ''"); return Ok(empty_vec); From 98d219ceac8aff59b036b44b6dc8306dd69f2cda Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Mon, 29 Apr 2024 18:13:11 +0200 Subject: [PATCH 6/9] Adding widestring import --- libraries/extensions/ros2-bridge/msg-gen/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs index 9e598a069..b3bd95f11 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs @@ -236,6 +236,7 @@ where quote! {}, quote! { use serde::{Serialize, Deserialize}; + use widestring; }, quote! {}, ) From 92e0edbd678185fb981cfe9dd74602e325cd2f1d Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Mon, 29 Apr 2024 19:47:17 +0200 Subject: [PATCH 7/9] fix import widestring in `ros2_bridge` --- libraries/extensions/ros2-bridge/msg-gen/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs index b3bd95f11..e1fe6cf19 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs @@ -236,7 +236,6 @@ where quote! {}, quote! { use serde::{Serialize, Deserialize}; - use widestring; }, quote! {}, ) @@ -263,6 +262,12 @@ where } } + impl ffi::U16String { + fn from_str(arg: &str) -> Self { + Self { chars: crate::_core::widestring::U16String::from_str(arg).into_vec()} + } + } + #(#message_struct_impls)* #cxx_bridge_impls From 3521e10d7b2c7508125cc61b4d4b510d622ec422 Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Tue, 30 Apr 2024 15:20:04 +0200 Subject: [PATCH 8/9] Use or_insert_with when registering package and raise glob error --- .../ros2-bridge/msg-gen/src/parser/package.rs | 100 +++++++----------- 1 file changed, 41 insertions(+), 59 deletions(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs index dd9104e1c..8900a722e 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/parser/package.rs @@ -26,72 +26,54 @@ fn get_ros_msgs_each_package>(root_dir: P) -> Result + "/*." + ros_format; let mut visited_files = vec![]; - for entry in glob(&pattern).expect("Failed to read glob pattern") { - match entry { - Ok(path) => { - let file_name = path - .clone() - .file_name() - .unwrap() - .to_str() - .unwrap() - .to_string(); + for entry in glob(&pattern).context("Failed to read glob pattern")? { + let path = entry.context("Could not glob given path")?; + let file_name = path + .clone() + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string(); - let package = path - .parent() - .context("Should have a msg folder")? - .parent() - .context("should have a package folder")? - .file_name() - .context("folder name should exist")? - .to_string_lossy() - .to_string(); + let package = path + .parent() + .context("Should have a msg folder")? + .parent() + .context("should have a package folder")? + .file_name() + .context("folder name should exist")? + .to_string_lossy() + .to_string(); - // Hack - if file_name == "libstatistics_collector" { - continue; - } else if visited_files.contains(&(package.clone(), file_name.clone())) { - warn!( + // Hack + if file_name == "libstatistics_collector" { + continue; + } else if visited_files.contains(&(package.clone(), file_name.clone())) { + warn!( "found two versions of package: {:?}, message: {:?}. will skip the one in: {:#?}", package, file_name, path ); - continue; - } else { - visited_files.push((package.clone(), file_name.clone())); - } + continue; + } else { + visited_files.push((package.clone(), file_name.clone())); + } + + let p = map + .entry(package.clone()) + .or_insert_with(|| Package::new(package.clone())); - match map.get_mut(&package) { - Some(p) => match ros_format { - "msg" => { - p.messages.push(parse_message_file(&package, path.clone())?); - } - "srv" => { - p.services.push(parse_service_file(&package, path.clone())?); - } - "action" => { - p.actions.push(parse_action_file(&package, path.clone())?); - } - _ => todo!(), - }, - None => { - let mut p = Package::new(package.clone()); - match ros_format { - "msg" => { - p.messages.push(parse_message_file(&package, path.clone())?); - } - "srv" => { - p.services.push(parse_service_file(&package, path.clone())?); - } - "action" => { - p.actions.push(parse_action_file(&package, path.clone())?); - } - _ => todo!(), - } - map.insert(package, p); - } - }; + match ros_format { + "msg" => { + p.messages.push(parse_message_file(&package, path.clone())?); + } + "srv" => { + p.services.push(parse_service_file(&package, path.clone())?); + } + "action" => { + p.actions.push(parse_action_file(&package, path.clone())?); } - Err(e) => eprintln!("{:?}", e), + _ => todo!(), } } } From bf4e9e283cef744a9aa668a82ffaa06d88c3faa5 Mon Sep 17 00:00:00 2001 From: haixuanTao Date: Tue, 30 Apr 2024 16:40:22 +0200 Subject: [PATCH 9/9] make chars public --- libraries/extensions/ros2-bridge/msg-gen/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs index e1fe6cf19..c64f809bf 100644 --- a/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs +++ b/libraries/extensions/ros2-bridge/msg-gen/src/lib.rs @@ -248,7 +248,7 @@ where #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct U16String { - chars: Vec, + pub chars: Vec, } #(#shared_type_defs)*