diff --git a/mavlink-bindgen/src/parser.rs b/mavlink-bindgen/src/parser.rs index 447367e129..dce7263129 100644 --- a/mavlink-bindgen/src/parser.rs +++ b/mavlink-bindgen/src/parser.rs @@ -1134,39 +1134,23 @@ pub fn parse_profile( match stack.last() { Some(&MavXmlElement::Enum) => { if attr.key.into_inner() == b"name" { - mavenum.name = attr - .value - .clone() - .split(|b| *b == b'_') - .map(|x| x.to_ascii_lowercase()) - .map(|mut v| { - v[0] = v[0].to_ascii_uppercase(); - String::from_utf8(v).unwrap() - }) - .collect(); + mavenum.name = to_pascal_case(attr.value); //mavenum.name = attr.value.clone(); } } Some(&MavXmlElement::Entry) => { match attr.key.into_inner() { b"name" => { - let name = String::from_utf8(attr.value.to_vec()).unwrap(); - entry.name = name; + entry.name = String::from_utf8_lossy(&attr.value).to_string(); } b"value" => { + let value = String::from_utf8_lossy(&attr.value); // Deal with hexadecimal numbers - if attr.value.starts_with(b"0x") { - entry.value = Some( - u32::from_str_radix( - std::str::from_utf8(&attr.value[2..]).unwrap(), - 16, - ) - .unwrap(), - ); - } else { - let s = std::str::from_utf8(&attr.value[..]).unwrap(); - entry.value = Some(s.parse::().unwrap()); - } + let (src, radix) = value + .strip_prefix("0x") + .map(|value| (value, 16)) + .unwrap_or((value.as_ref(), 10)); + entry.value = u32::from_str_radix(src, radix).ok(); } _ => (), } @@ -1187,11 +1171,11 @@ pub fn parse_profile( .collect::>() .join(""); */ - message.name = String::from_utf8(attr.value.to_vec()).unwrap(); + message.name = String::from_utf8_lossy(&attr.value).to_string(); } b"id" => { - let s = std::str::from_utf8(&attr.value).unwrap(); - message.id = s.parse::().unwrap(); + message.id = + String::from_utf8_lossy(&attr.value).parse().unwrap(); } _ => (), } @@ -1199,33 +1183,24 @@ pub fn parse_profile( Some(&MavXmlElement::Field) => { match attr.key.into_inner() { b"name" => { - let name = String::from_utf8(attr.value.to_vec()).unwrap(); - field.name = name; - if field.name == "type" { - field.name = "mavtype".to_string(); - } + let name = String::from_utf8_lossy(&attr.value); + field.name = if name == "type" { + "mavtype".to_string() + } else { + name.to_string() + }; } b"type" => { - let s = std::str::from_utf8(&attr.value).unwrap(); - field.mavtype = MavType::parse_type(s).unwrap(); + let r#type = String::from_utf8_lossy(&attr.value); + field.mavtype = MavType::parse_type(&r#type).unwrap(); } b"enum" => { - field.enumtype = Some( - attr.value - .clone() - .split(|b| *b == b'_') - .map(|x| x.to_ascii_lowercase()) - .map(|mut v| { - v[0] = v[0].to_ascii_uppercase(); - String::from_utf8(v).unwrap() - }) - .collect(), - ); + field.enumtype = Some(to_pascal_case(attr.value)); //field.enumtype = Some(attr.value.clone()); } b"display" => { field.display = - Some(String::from_utf8(attr.value.to_vec()).unwrap()); + Some(String::from_utf8_lossy(&attr.value).to_string()); } _ => (), } @@ -1235,8 +1210,8 @@ pub fn parse_profile( entry.params = Some(vec![]); } if attr.key.into_inner() == b"index" { - let s = std::str::from_utf8(&attr.value).unwrap(); - paramid = Some(s.parse::().unwrap()); + paramid = + Some(String::from_utf8_lossy(&attr.value).parse().unwrap()); } } _ => (), @@ -1253,11 +1228,11 @@ pub fn parse_profile( let attr = attr.unwrap(); match attr.key.into_inner() { b"name" => { - entry.name = String::from_utf8(attr.value.to_vec()).unwrap(); + entry.name = String::from_utf8_lossy(&attr.value).to_string(); } b"value" => { - let s = std::str::from_utf8(&attr.value).unwrap(); - entry.value = Some(s.parse().unwrap()); + entry.value = + Some(String::from_utf8_lossy(&attr.value).parse().unwrap()); } _ => (), } @@ -1267,7 +1242,7 @@ pub fn parse_profile( _ => (), }, Ok(Event::Text(bytes)) => { - let s = String::from_utf8(bytes.to_vec()).unwrap(); + let s = String::from_utf8_lossy(&bytes).to_string(); use self::MavXmlElement::*; match (stack.last(), stack.get(stack.len() - 2)) { @@ -1284,15 +1259,16 @@ pub fn parse_profile( entry.description = Some(s.replace('\n', " ")); } (Some(&Param), Some(&Entry)) => { - if let Some(params) = &mut entry.params { + if let Some(params) = entry.params.as_mut() { // Some messages can jump between values, like: // 0, 1, 2, 7 - if params.len() < paramid.unwrap() { - for index in params.len()..paramid.unwrap() { + let paramid = paramid.unwrap(); + if params.len() < paramid { + for index in params.len()..paramid { params.insert(index, String::from("The use of this parameter (if any), must be defined in the requested message. By default assumed not used (0).")); } } - params[paramid.unwrap() - 1] = s; + params[paramid - 1] = s; } } (Some(&Include), Some(&Mavlink)) => { @@ -1490,3 +1466,19 @@ impl MavXmlFilter { } } } + +fn to_pascal_case(text: impl AsRef<[u8]>) -> String { + text.as_ref() + .split(|c| *c == b'_') + .map(String::from_utf8_lossy) + .map(capitalize_word) + .collect() +} + +fn capitalize_word(text: impl AsRef) -> String { + let mut chars = text.as_ref().chars(); + match chars.next() { + None => String::new(), + Some(char) => char.to_uppercase().to_string() + &chars.as_str().to_ascii_lowercase(), + } +} diff --git a/mavlink/build/main.rs b/mavlink/build/main.rs index 4d1cfd4c73..64f3aea0ab 100644 --- a/mavlink/build/main.rs +++ b/mavlink/build/main.rs @@ -21,10 +21,8 @@ fn main() -> ExitCode { } // find & apply patches to XML definitions to avoid crashes - let mut patch_dir = src_dir.to_path_buf(); - patch_dir.push("build/patches"); - let mut mavlink_dir = src_dir.to_path_buf(); - mavlink_dir.push("mavlink"); + let patch_dir = src_dir.join("build/patches"); + let mavlink_dir = src_dir.join("mavlink"); if let Ok(dir) = read_dir(patch_dir) { for entry in dir.flatten() { @@ -40,8 +38,7 @@ fn main() -> ExitCode { } } - let mut definitions_dir = src_dir.to_path_buf(); - definitions_dir.push("mavlink/message_definitions/v1.0"); + let definitions_dir = src_dir.join("mavlink/message_definitions/v1.0"); let out_dir = env::var("OUT_DIR").unwrap();