From f47c61f74b7255bd7e37d82c56410812e1dd9551 Mon Sep 17 00:00:00 2001 From: Salman Abuhaimed Date: Sun, 31 Mar 2024 15:31:57 +0300 Subject: [PATCH] print bindgen cli error --- mavlink-bindgen/src/cli.rs | 9 +++++---- mavlink-bindgen/src/error.rs | 12 +++++++++--- mavlink-bindgen/src/lib.rs | 4 ++-- mavlink-bindgen/src/main.rs | 13 +++++++++++-- mavlink-bindgen/src/parser.rs | 24 ++++++++++++++++++------ mavlink/build/main.rs | 17 +++++++++++++---- 6 files changed, 58 insertions(+), 21 deletions(-) diff --git a/mavlink-bindgen/src/cli.rs b/mavlink-bindgen/src/cli.rs index 02eb59038f..30fee8a843 100644 --- a/mavlink-bindgen/src/cli.rs +++ b/mavlink-bindgen/src/cli.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use clap::Parser; -use mavlink_bindgen::{emit_cargo_build_messages, format_generated_code, generate}; +use mavlink_bindgen::{emit_cargo_build_messages, format_generated_code, generate, BindGenError}; #[derive(Parser)] struct Cli { @@ -13,10 +13,9 @@ struct Cli { emit_cargo_build_messages: bool, } -pub fn main() { +pub fn main() -> Result<(), BindGenError> { let args = Cli::parse(); - let result = generate(args.definitions_dir, args.destination_dir) - .expect("failed to generate MAVLink Rust bindings"); + let result = generate(args.definitions_dir, args.destination_dir)?; if args.format_generated_code { format_generated_code(&result); @@ -25,4 +24,6 @@ pub fn main() { if args.emit_cargo_build_messages { emit_cargo_build_messages(&result); } + + Ok(()) } diff --git a/mavlink-bindgen/src/error.rs b/mavlink-bindgen/src/error.rs index fec283634b..957ec5506d 100644 --- a/mavlink-bindgen/src/error.rs +++ b/mavlink-bindgen/src/error.rs @@ -3,19 +3,25 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum BindGenError { /// Represents a failure to read the MAVLink definitions directory. - #[error("Could not read definitions directory {path}")] + #[error("Could not read definitions directory {path}: {source}")] CouldNotReadDefinitionsDirectory { source: std::io::Error, path: std::path::PathBuf, }, + /// Represents a failure to read the MAVLink definitions directory. + #[error("Could not read definition file {path}: {source}")] + CouldNotReadDefinitionFile { + source: std::io::Error, + path: std::path::PathBuf, + }, /// Represents a failure to read a directory entry in the MAVLink definitions directory. - #[error("Could not read MAVLink definitions directory entry {path}")] + #[error("Could not read MAVLink definitions directory entry {path}: {source}")] CouldNotReadDirectoryEntryInDefinitionsDirectory { source: std::io::Error, path: std::path::PathBuf, }, /// Represents a failure to create a Rust file for the generated MAVLink bindings. - #[error("Could not create Rust bindings file {dest_path}")] + #[error("Could not create Rust bindings file {dest_path}: {source}")] CouldNotCreateRustBindingsFile { source: std::io::Error, dest_path: std::path::PathBuf, diff --git a/mavlink-bindgen/src/lib.rs b/mavlink-bindgen/src/lib.rs index f5e63da800..3448fe88da 100644 --- a/mavlink-bindgen/src/lib.rs +++ b/mavlink-bindgen/src/lib.rs @@ -1,4 +1,4 @@ -use crate::error::BindGenError; +pub use crate::error::BindGenError; use std::fs::{read_dir, File}; use std::io::BufWriter; use std::ops::Deref; @@ -64,7 +64,7 @@ fn _generate( })?); // generate code - parser::generate(&definitions_dir, &definition_file, &mut outf); + parser::generate(&definitions_dir, &definition_file, &mut outf)?; bindings.push(GeneratedBinding { module_name, diff --git a/mavlink-bindgen/src/main.rs b/mavlink-bindgen/src/main.rs index 660ba5ec7f..f2c68ba787 100644 --- a/mavlink-bindgen/src/main.rs +++ b/mavlink-bindgen/src/main.rs @@ -1,11 +1,20 @@ #![recursion_limit = "256"] +use std::process::ExitCode; + #[cfg(feature = "cli")] mod cli; -pub fn main() { +fn main() -> ExitCode { #[cfg(feature = "cli")] - cli::main(); + if let Err(e) = cli::main() { + eprintln!("{e}"); + return ExitCode::FAILURE; + } + #[cfg(not(feature = "cli"))] panic!("Compiled without cli feature"); + + #[cfg(feature = "cli")] + ExitCode::SUCCESS } diff --git a/mavlink-bindgen/src/parser.rs b/mavlink-bindgen/src/parser.rs index 0d273e663d..1a6eaba7e3 100644 --- a/mavlink-bindgen/src/parser.rs +++ b/mavlink-bindgen/src/parser.rs @@ -17,6 +17,8 @@ use quote::{format_ident, quote}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::error::BindGenError; + #[derive(Debug, PartialEq, Clone, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MavProfile { @@ -1033,7 +1035,7 @@ pub fn parse_profile( definitions_dir: &Path, definition_file: &Path, parsed_files: &mut HashSet, -) -> MavProfile { +) -> Result { let in_path = Path::new(&definitions_dir).join(definition_file); parsed_files.insert(in_path.clone()); // Keep track of which files have been parsed @@ -1049,7 +1051,11 @@ pub fn parse_profile( let mut xml_filter = MavXmlFilter::default(); let mut events: Vec> = Vec::new(); - let mut reader = Reader::from_reader(BufReader::new(File::open(in_path).unwrap())); + let file = File::open(&in_path).map_err(|e| BindGenError::CouldNotReadDefinitionFile { + source: e, + path: in_path.to_path_buf(), + })?; + let mut reader = Reader::from_reader(BufReader::new(file)); reader.trim_text(true); reader.trim_text_end(true); @@ -1331,7 +1337,7 @@ pub fn parse_profile( let include_file = Path::new(&definitions_dir).join(include.clone()); if !parsed_files.contains(&include_file) { let included_profile = - parse_profile(definitions_dir, &include, parsed_files); + parse_profile(definitions_dir, &include, parsed_files)?; for message in included_profile.messages.values() { profile.add_message(message); } @@ -1354,18 +1360,24 @@ pub fn parse_profile( } //let profile = profile.update_messages(); //TODO verify no longer needed - profile.update_enums() + Ok(profile.update_enums()) } /// Generate protobuf represenation of mavlink message set /// Generate rust representation of mavlink message set with appropriate conversion methods -pub fn generate(definitions_dir: &Path, definition_file: &Path, output_rust: &mut W) { +pub fn generate( + definitions_dir: &Path, + definition_file: &Path, + output_rust: &mut W, +) -> Result<(), BindGenError> { let mut parsed_files: HashSet = HashSet::new(); - let profile = parse_profile(definitions_dir, definition_file, &mut parsed_files); + let profile = parse_profile(definitions_dir, definition_file, &mut parsed_files)?; // rust file let rust_tokens = profile.emit_rust(); writeln!(output_rust, "{rust_tokens}").unwrap(); + + Ok(()) } /// CRC operates over names of the message and names of its fields diff --git a/mavlink/build/main.rs b/mavlink/build/main.rs index 7206d20658..4d1cfd4c73 100644 --- a/mavlink/build/main.rs +++ b/mavlink/build/main.rs @@ -3,9 +3,9 @@ use std::env; use std::fs::read_dir; use std::path::Path; -use std::process::Command; +use std::process::{Command, ExitCode}; -pub fn main() { +fn main() -> ExitCode { let src_dir = Path::new(env!("CARGO_MANIFEST_DIR")); // Update and init submodule @@ -17,6 +17,7 @@ pub fn main() { .status() { eprintln!("{error}"); + return ExitCode::FAILURE; } // find & apply patches to XML definitions to avoid crashes @@ -34,6 +35,7 @@ pub fn main() { .status() { eprintln!("{error}"); + return ExitCode::FAILURE; } } } @@ -43,11 +45,18 @@ pub fn main() { let out_dir = env::var("OUT_DIR").unwrap(); - let result = mavlink_bindgen::generate(definitions_dir, out_dir) - .expect("Failed to generate Rust MAVLink bindings"); + let result = match mavlink_bindgen::generate(definitions_dir, out_dir) { + Ok(r) => r, + Err(e) => { + eprintln!("{e}"); + return ExitCode::FAILURE; + } + }; #[cfg(feature = "format-generated-code")] mavlink_bindgen::format_generated_code(&result); mavlink_bindgen::emit_cargo_build_messages(&result); + + ExitCode::SUCCESS }