#![allow( clippy::cast_sign_loss, clippy::cognitive_complexity, clippy::default_trait_access, clippy::enum_glob_use, clippy::inherent_to_string, clippy::items_after_statements, clippy::large_enum_variant, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::module_name_repetitions, clippy::needless_pass_by_value, clippy::new_without_default, clippy::nonminimal_bool, clippy::option_if_let_else, clippy::or_fun_call, clippy::redundant_else, clippy::shadow_unrelated, clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, clippy::too_many_arguments, clippy::too_many_lines, clippy::toplevel_ref_arg, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983 clippy::wrong_self_convention )] mod app; mod gen; mod output; mod syntax; use crate::gen::error::{report, Result}; use crate::gen::fs; use crate::gen::include::{self, Include}; use crate::output::Output; use std::io::{self, Write}; use std::path::PathBuf; use std::process; #[derive(Debug)] struct Opt { input: Option, header: bool, cxx_impl_annotations: Option, include: Vec, outputs: Vec, } fn main() { if let Err(err) = try_main() { let _ = writeln!(io::stderr(), "cxxbridge: {}", report(err)); process::exit(1); } } enum Kind { GeneratedHeader, GeneratedImplementation, Header, } fn try_main() -> Result<()> { let opt = app::from_args(); let mut outputs = Vec::new(); let mut gen_header = false; let mut gen_implementation = false; for output in opt.outputs { let kind = if opt.input.is_none() { Kind::Header } else if opt.header || output.ends_with(".h") || output.ends_with(".hh") || output.ends_with(".hpp") { gen_header = true; Kind::GeneratedHeader } else { gen_implementation = true; Kind::GeneratedImplementation }; outputs.push((output, kind)); } let gen = gen::Opt { include: opt.include, cxx_impl_annotations: opt.cxx_impl_annotations, gen_header, gen_implementation, ..Default::default() }; let generated_code = if let Some(input) = opt.input { gen::generate_from_path(&input, &gen) } else { Default::default() }; for (output, kind) in outputs { let content = match kind { Kind::GeneratedHeader => &generated_code.header, Kind::GeneratedImplementation => &generated_code.implementation, Kind::Header => include::HEADER.as_bytes(), }; match output { Output::Stdout => drop(io::stdout().write_all(content)), Output::File(path) => fs::write(path, content)?, } } Ok(()) }