blob: aa60b05cdd82ba9205d1e3a65e65531522fb4b0c [file] [log] [blame]
Adrian Taylor9fc08462020-08-14 10:51:00 -07001//! The CXX code generator for constructing and compiling C++ code.
2//!
3//! This is intended to be embedded into higher-level code generators.
4
5mod gen;
6mod syntax;
7
Adrian Taylor0926f642020-08-25 13:08:06 -07008pub use crate::gen::Opt;
Adrian Taylor9fc08462020-08-14 10:51:00 -07009use proc_macro2::TokenStream;
10
David Tolnay366c41a2020-08-29 22:28:21 -070011pub use crate::gen::{Error, Result};
12
13/// Results of code generation.
14pub struct GeneratedCode {
15 /// The bytes of a C++ header file.
16 pub header: Vec<u8>,
17 /// The bytes of a C++ implementation file (e.g. .cc, cpp etc.)
18 pub cxx: Vec<u8>,
19}
Adrian Taylor9fc08462020-08-14 10:51:00 -070020
21/// Generate C++ bindings code from a Rust token stream. This should be a Rust
22/// token stream which somewhere contains a `#[cxx::bridge] mod {}`.
Adrian Taylor0926f642020-08-25 13:08:06 -070023pub fn generate_header_and_cc(rust_source: TokenStream, opt: Opt) -> Result<GeneratedCode> {
David Tolnay366c41a2020-08-29 22:28:21 -070024 let syntax = syn::parse2(rust_source)?;
25 match gen::generate(syntax, opt, true, true) {
26 Ok((Some(header), Some(cxx))) => Ok(GeneratedCode { header, cxx }),
27 Err(err) => Err(err),
28 _ => panic!("Unexpected generation"),
29 }
Adrian Taylor9fc08462020-08-14 10:51:00 -070030}
Adrian Taylor593eddb2020-08-21 23:46:08 -070031
32#[cfg(test)]
33mod test {
34 use quote::quote;
35
36 #[test]
37 fn test_positive() {
38 let rs = quote! {
39 #[cxx::bridge]
40 mod ffi {
41 extern "C" {
42 fn in_C();
43 }
44 extern "Rust" {
45 fn in_rs();
46 }
47 }
48 };
49 let code = crate::generate_header_and_cc(rs).unwrap();
50 assert!(code.cxx.len() > 0);
51 assert!(code.header.len() > 0);
52 }
53
54 #[test]
55 fn test_negative() {
56 let rs = quote! {};
57 assert!(crate::generate_header_and_cc(rs).is_err())
58 }
59}