diff --git a/r2r_common/Cargo.toml b/r2r_common/Cargo.toml index bd31d96..c2743c9 100644 --- a/r2r_common/Cargo.toml +++ b/r2r_common/Cargo.toml @@ -15,6 +15,7 @@ bindgen = "0.63.0" itertools = "0.10.5" sha2 = "0.10.6" os_str_bytes = "6.5.1" +regex = "1.8.4" [features] doc-only = [] diff --git a/r2r_common/src/lib.rs b/r2r_common/src/lib.rs index 40f25d4..279508d 100644 --- a/r2r_common/src/lib.rs +++ b/r2r_common/src/lib.rs @@ -6,6 +6,7 @@ use std::env; use std::fs::{self, File}; use std::io::Read; use std::path::Path; +use regex::*; #[cfg(not(feature = "doc-only"))] const SUPPORTED_ROS_DISTROS: &[&str] = &["foxy", "galactic", "humble", "rolling"]; @@ -376,6 +377,18 @@ pub fn as_map(included_msgs: &[RosMsg]) -> HashMap<&str, HashMap<&str, Vec<&str> msgs } +/// camel case to to snake case adapted from from ros_idl_cmake +/// note that this is not a general camel to snake converter. +pub fn camel_to_snake(s: &str) -> String { + let re1 = Regex::new(r"(.)([A-Z][a-z]+)").unwrap(); + let re2 = Regex::new(r"([a-z0-9])([A-Z])").unwrap(); + + let s = re1.replace_all(s, "${1}_${2}"); + let s = re2.replace_all(&s, "${1}_${2}"); + + s.to_lowercase() +} + #[cfg(test)] mod tests { use super::*; @@ -411,4 +424,11 @@ std_msgs/msg/String assert_eq!(map.get("std_msgs").unwrap().get("msg").unwrap()[0], "Bool"); assert_eq!(map.get("std_msgs").unwrap().get("msg").unwrap()[1], "String"); } + + #[test] + fn test_snake_case() { + assert_eq!(camel_to_snake("AB01CD02"), "ab01_cd02"); + assert_eq!(camel_to_snake("UnboundedSequences"), "unbounded_sequences"); + assert_eq!(camel_to_snake("WStrings"), "w_strings"); + } } diff --git a/r2r_msg_gen/Cargo.toml b/r2r_msg_gen/Cargo.toml index 70372c2..bf9e849 100644 --- a/r2r_msg_gen/Cargo.toml +++ b/r2r_msg_gen/Cargo.toml @@ -24,7 +24,6 @@ rayon = "1.7.0" bindgen = "0.63.0" r2r_rcl = { path = "../r2r_rcl", version = "0.3.8" } r2r_common = { path = "../r2r_common", version = "0.3.7" } -heck = "0.4.0" quote = "1.0.28" syn = { version = "2.0.18", features = ["full"] } rayon = "1.7.0" diff --git a/r2r_msg_gen/build.rs b/r2r_msg_gen/build.rs index 5301bc9..31ac0f4 100644 --- a/r2r_msg_gen/build.rs +++ b/r2r_msg_gen/build.rs @@ -1,12 +1,11 @@ use bindgen::Bindings; -use heck::ToSnakeCase; use itertools::chain; use itertools::iproduct; use itertools::Either; use itertools::Itertools; use quote::format_ident; use quote::quote; -use r2r_common::RosMsg; +use r2r_common::{RosMsg, camel_to_snake}; use rayon::prelude::*; use std::fs::File; use std::fs::OpenOptions; @@ -118,7 +117,7 @@ fn generate_includes(bindgen_dir: &Path, msg_list: &[RosMsg]) { } = msg; // filename is certainly CamelCase -> snake_case. convert - let include_filename = name.to_snake_case(); + let include_filename = camel_to_snake(&name); [ format!("#include <{module}/{prefix}/{include_filename}.h>"),