blob: 091c7cc4cc46be3491964d78c9a9987c733f0bb5 [file] [log] [blame]
David Tolnaye3daefb2020-05-11 12:52:53 -07001//! [![github]](https://github.com/dtolnay/cxx) [![crates-io]](https://crates.io/crates/cxx) [![docs-rs]](https://docs.rs/cxx)
2//!
3//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
David Tolnay864ab8c2020-03-29 22:25:40 -07006//!
7//! <br>
8//!
David Tolnay7db73692019-10-20 14:51:12 -04009//! This library provides a **safe** mechanism for calling C++ code from Rust
10//! and Rust code from C++, not subject to the many ways that things can go
11//! wrong when using bindgen or cbindgen to generate unsafe C-style bindings.
12//!
David Tolnayccd39752020-01-08 09:33:51 -080013//! This doesn't change the fact that 100% of C++ code is unsafe. When auditing
14//! a project, you would be on the hook for auditing all the unsafe Rust code
15//! and *all* the C++ code. The core safety claim under this new model is that
16//! auditing just the C++ side would be sufficient to catch all problems, i.e.
17//! the Rust side can be 100% safe.
18//!
David Tolnay7db73692019-10-20 14:51:12 -040019//! <br>
20//!
David Tolnay2a0a80a2020-10-11 03:49:29 -070021//! *Compiler support: requires rustc 1.43+ and c++11 or newer*<br>
David Tolnay0e078f72020-05-11 20:49:59 -070022//! *[Release notes](https://github.com/dtolnay/cxx/releases)*
David Tolnay7db73692019-10-20 14:51:12 -040023//!
24//! <br>
25//!
26//! # Overview
27//!
28//! The idea is that we define the signatures of both sides of our FFI boundary
29//! embedded together in one Rust module (the next section shows an example).
30//! From this, CXX receives a complete picture of the boundary to perform static
31//! analyses against the types and function signatures to uphold both Rust's and
32//! C++'s invariants and requirements.
33//!
34//! If everything checks out statically, then CXX uses a pair of code generators
35//! to emit the relevant `extern "C"` signatures on both sides together with any
36//! necessary static assertions for later in the build process to verify
37//! correctness. On the Rust side this code generator is simply an attribute
38//! procedural macro. On the C++ side it can be a small Cargo build script if
39//! your build is managed by Cargo, or for other build systems like Bazel or
40//! Buck we provide a command line tool which generates the header and source
41//! file and should be easy to integrate.
42//!
43//! The resulting FFI bridge operates at zero or negligible overhead, i.e. no
44//! copying, no serialization, no memory allocation, no runtime checks needed.
45//!
46//! The FFI signatures are able to use native types from whichever side they
47//! please, such as Rust's `String` or C++'s `std::string`, Rust's `Box` or
48//! C++'s `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any
49//! combination. CXX guarantees an ABI-compatible signature that both sides
50//! understand, based on builtin bindings for key standard library types to
51//! expose an idiomatic API on those types to the other language. For example
52//! when manipulating a C++ string from Rust, its `len()` method becomes a call
53//! of the `size()` member function defined by C++; when manipulation a Rust
54//! string from C++, its `size()` member function calls Rust's `len()`.
55//!
56//! <br>
57//!
58//! # Example
59//!
David Tolnay4ca366f2020-11-10 20:55:31 -080060//! In this example we are writing a Rust application that wishes to take
61//! advantage of an existing C++ client for a large-file blobstore service. The
62//! blobstore supports a `put` operation for a discontiguous buffer upload. For
63//! example we might be uploading snapshots of a circular buffer which would
64//! tend to consist of 2 chunks, or fragments of a file spread across memory for
65//! some other reason.
66//!
David Tolnay278f6fc2020-09-01 16:16:57 -070067//! A runnable version of this example is provided under the *demo* directory of
David Tolnay7614e772020-11-10 22:55:40 -080068//! <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that
David Tolnay278f6fc2020-09-01 16:16:57 -070069//! directory.
David Tolnay7db73692019-10-20 14:51:12 -040070//!
71//! ```no_run
72//! #[cxx::bridge]
73//! mod ffi {
74//! // Any shared structs, whose fields will be visible to both languages.
David Tolnay4ca366f2020-11-10 20:55:31 -080075//! struct BlobMetadata {
76//! size: usize,
77//! tags: Vec<String>,
David Tolnay7db73692019-10-20 14:51:12 -040078//! }
79//!
80//! extern "Rust" {
81//! // Zero or more opaque types which both languages can pass around but
82//! // only Rust can see the fields.
David Tolnay4ca366f2020-11-10 20:55:31 -080083//! type MultiBuf;
David Tolnay7db73692019-10-20 14:51:12 -040084//!
85//! // Functions implemented in Rust.
David Tolnay4ca366f2020-11-10 20:55:31 -080086//! fn next_chunk(buf: &mut MultiBuf) -> &[u8];
87//! }
88//!
David Tolnay7be5b1f2020-11-11 10:48:32 -080089//! unsafe extern "C++" {
David Tolnay4ca366f2020-11-10 20:55:31 -080090//! // One or more headers with the matching C++ declarations. Our code
91//! // generators don't read it but it gets #include'd and used in static
92//! // assertions to ensure our picture of the FFI boundary is accurate.
93//! include!("demo/include/blobstore.h");
94//!
95//! // Zero or more opaque types which both languages can pass around but
96//! // only C++ can see the fields.
97//! type BlobstoreClient;
98//!
99//! // Functions implemented in C++.
100//! fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
101//! fn put(&self, parts: &mut MultiBuf) -> u64;
102//! fn tag(&self, blobid: u64, tag: &str);
103//! fn metadata(&self, blobid: u64) -> BlobMetadata;
David Tolnay7db73692019-10-20 14:51:12 -0400104//! }
105//! }
106//! #
David Tolnay4ca366f2020-11-10 20:55:31 -0800107//! # pub struct MultiBuf;
David Tolnay7db73692019-10-20 14:51:12 -0400108//! #
David Tolnay4ca366f2020-11-10 20:55:31 -0800109//! # fn next_chunk(_buf: &mut MultiBuf) -> &[u8] {
110//! # unimplemented!()
David Tolnay7db73692019-10-20 14:51:12 -0400111//! # }
112//! #
113//! # fn main() {}
114//! ```
115//!
David Tolnay4ca366f2020-11-10 20:55:31 -0800116//! Now we simply provide Rust definitions of all the things in the `extern
117//! "Rust"` block and C++ definitions of all the things in the `extern "C++"`
118//! block, and get to call back and forth safely.
David Tolnay7db73692019-10-20 14:51:12 -0400119//!
120//! Here are links to the complete set of source files involved in the demo:
121//!
David Tolnay278f6fc2020-09-01 16:16:57 -0700122//! - [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs)
123//! - [demo/build.rs](https://github.com/dtolnay/cxx/blob/master/demo/build.rs)
David Tolnay4ca366f2020-11-10 20:55:31 -0800124//! - [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h)
125//! - [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc)
David Tolnay7db73692019-10-20 14:51:12 -0400126//!
127//! To look at the code generated in both languages for the example by the CXX
128//! code generators:
129//!
130//! ```console
131//! # run Rust code generator and print to stdout
132//! # (requires https://github.com/dtolnay/cargo-expand)
David Tolnay278f6fc2020-09-01 16:16:57 -0700133//! $ cargo expand --manifest-path demo/Cargo.toml
David Tolnay7db73692019-10-20 14:51:12 -0400134//!
135//! # run C++ code generator and print to stdout
David Tolnay278f6fc2020-09-01 16:16:57 -0700136//! $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs
David Tolnay7db73692019-10-20 14:51:12 -0400137//! ```
138//!
139//! <br>
140//!
141//! # Details
142//!
143//! As seen in the example, the language of the FFI boundary involves 3 kinds of
144//! items:
145//!
146//! - **Shared structs** &mdash; their fields are made visible to both
147//! languages. The definition written within cxx::bridge is the single source
148//! of truth.
149//!
150//! - **Opaque types** &mdash; their fields are secret from the other language.
151//! These cannot be passed across the FFI by value but only behind an
152//! indirection, such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can
153//! be a type alias for an arbitrarily complicated generic language-specific
154//! type depending on your use case.
155//!
156//! - **Functions** &mdash; implemented in either language, callable from the
157//! other language.
158//!
David Tolnayc72a9f62020-11-11 10:56:26 -0800159//! Within the `extern "C++"` part of the CXX bridge we list the types and
David Tolnay7db73692019-10-20 14:51:12 -0400160//! functions for which C++ is the source of truth, as well as the header(s)
161//! that declare those APIs. In the future it's possible that this section could
162//! be generated bindgen-style from the headers but for now we need the
163//! signatures written out; static assertions will verify that they are
164//! accurate.
165//!
166//! Within the `extern "Rust"` part, we list types and functions for which Rust
167//! is the source of truth. These all implicitly refer to the `super` module,
168//! the parent module of the CXX bridge. You can think of the two items listed
169//! in the example above as being like `use super::ThingR` and `use
170//! super::print_r` except re-exported to C++. The parent module will either
171//! contain the definitions directly for simple things, or contain the relevant
172//! `use` statements to bring them into scope from elsewhere.
173//!
174//! Your function implementations themselves, whether in C++ or Rust, *do not*
175//! need to be defined as `extern "C"` ABI or no\_mangle. CXX will put in the
176//! right shims where necessary to make it all work.
177//!
178//! <br>
179//!
180//! # Comparison vs bindgen and cbindgen
181//!
182//! Notice that with CXX there is repetition of all the function signatures:
183//! they are typed out once where the implementation is defined (in C++ or Rust)
184//! and again inside the cxx::bridge module, though compile-time assertions
185//! guarantee these are kept in sync. This is different from [bindgen] and
186//! [cbindgen] where function signatures are typed by a human once and the tool
187//! consumes them in one language and emits them in the other language.
188//!
189//! [bindgen]: https://github.com/rust-lang/rust-bindgen
190//! [cbindgen]: https://github.com/eqrion/cbindgen/
191//!
192//! This is because CXX fills a somewhat different role. It is a lower level
193//! tool than bindgen or cbindgen in a sense; you can think of it as being a
194//! replacement for the concept of `extern "C"` signatures as we know them,
195//! rather than a replacement for a bindgen. It would be reasonable to build a
196//! higher level bindgen-like tool on top of CXX which consumes a C++ header
197//! and/or Rust module (and/or IDL like Thrift) as source of truth and generates
198//! the cxx::bridge, eliminating the repetition while leveraging the static
199//! analysis safety guarantees of CXX.
200//!
201//! But note in other ways CXX is higher level than the bindgens, with rich
202//! support for common standard library types. Frequently with bindgen when we
203//! are dealing with an idiomatic C++ API we would end up manually wrapping that
204//! API in C-style raw pointer functions, applying bindgen to get unsafe raw
205//! pointer Rust functions, and replicating the API again to expose those
206//! idiomatically in Rust. That's a much worse form of repetition because it is
207//! unsafe all the way through.
208//!
209//! By using a CXX bridge as the shared understanding between the languages,
210//! rather than `extern "C"` C-style signatures as the shared understanding,
211//! common FFI use cases become expressible using 100% safe code.
212//!
213//! It would also be reasonable to mix and match, using CXX bridge for the 95%
214//! of your FFI that is straightforward and doing the remaining few oddball
215//! signatures the old fashioned way with bindgen and cbindgen, if for some
216//! reason CXX's static restrictions get in the way. Please file an issue if you
217//! end up taking this approach so that we know what ways it would be worthwhile
218//! to make the tool more expressive.
219//!
220//! <br>
221//!
222//! # Cargo-based setup
223//!
224//! For builds that are orchestrated by Cargo, you will use a build script that
225//! runs CXX's C++ code generator and compiles the resulting C++ code along with
226//! any other C++ code for your crate.
227//!
228//! The canonical build script is as follows. The indicated line returns a
229//! [`cc::Build`] instance (from the usual widely used `cc` crate) on which you
230//! can set up any additional source files and compiler flags as normal.
231//!
232//! [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html
233//!
David Tolnaycc9ece52020-04-29 18:57:05 -0700234//! ```toml
235//! # Cargo.toml
236//!
237//! [build-dependencies]
David Tolnayc4999502020-10-08 18:18:12 -0700238//! cxx-build = "0.5"
David Tolnaycc9ece52020-04-29 18:57:05 -0700239//! ```
240//!
David Tolnay7db73692019-10-20 14:51:12 -0400241//! ```no_run
242//! // build.rs
243//!
244//! fn main() {
David Tolnayf8ed0732020-04-29 12:34:47 -0700245//! cxx_build::bridge("src/main.rs") // returns a cc::Build
David Tolnay278f6fc2020-09-01 16:16:57 -0700246//! .file("src/demo.cc")
Philip Craig7e14e2e2020-05-09 10:42:30 +0100247//! .flag_if_supported("-std=c++11")
David Tolnay7db73692019-10-20 14:51:12 -0400248//! .compile("cxxbridge-demo");
249//!
250//! println!("cargo:rerun-if-changed=src/main.rs");
David Tolnay278f6fc2020-09-01 16:16:57 -0700251//! println!("cargo:rerun-if-changed=src/demo.cc");
252//! println!("cargo:rerun-if-changed=include/demo.h");
David Tolnay7db73692019-10-20 14:51:12 -0400253//! }
254//! ```
255//!
256//! <br><br>
257//!
258//! # Non-Cargo setup
259//!
260//! For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate
261//! way of invoking the C++ code generator as a standalone command line tool.
262//! The tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be
David Tolnay7614e772020-11-10 22:55:40 -0800263//! built from the *gen/cmd* directory of <https://github.com/dtolnay/cxx>.
David Tolnay7db73692019-10-20 14:51:12 -0400264//!
265//! ```bash
266//! $ cargo install cxxbridge-cmd
267//!
268//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
269//! $ cxxbridge src/main.rs > path/to/mybridge.cc
270//! ```
271//!
272//! <br>
273//!
274//! # Safety
275//!
276//! Be aware that the design of this library is intentionally restrictive and
277//! opinionated! It isn't a goal to be powerful enough to handle arbitrary
278//! signatures in either language. Instead this project is about carving out a
279//! reasonably expressive set of functionality about which we can make useful
280//! safety guarantees today and maybe extend over time. You may find that it
281//! takes some practice to use CXX bridge effectively as it won't work in all
282//! the ways that you are used to.
283//!
284//! Some of the considerations that go into ensuring safety are:
285//!
286//! - By design, our paired code generators work together to control both sides
287//! of the FFI boundary. Ordinarily in Rust writing your own `extern "C"`
288//! blocks is unsafe because the Rust compiler has no way to know whether the
289//! signatures you've written actually match the signatures implemented in the
290//! other language. With CXX we achieve that visibility and know what's on the
291//! other side.
292//!
293//! - Our static analysis detects and prevents passing types by value that
294//! shouldn't be passed by value from C++ to Rust, for example because they
295//! may contain internal pointers that would be screwed up by Rust's move
296//! behavior.
297//!
298//! - To many people's surprise, it is possible to have a struct in Rust and a
299//! struct in C++ with exactly the same layout / fields / alignment /
300//! everything, and still not the same ABI when passed by value. This is a
301//! longstanding bindgen bug that leads to segfaults in absolutely
302//! correct-looking code ([rust-lang/rust-bindgen#778]). CXX knows about this
303//! and can insert the necessary zero-cost workaround transparently where
304//! needed, so go ahead and pass your structs by value without worries. This
305//! is made possible by owning both sides of the boundary rather than just
306//! one.
307//!
308//! - Template instantiations: for example in order to expose a UniquePtr\<T\>
309//! type in Rust backed by a real C++ unique\_ptr, we have a way of using a
310//! Rust trait to connect the behavior back to the template instantiations
311//! performed by the other language.
312//!
313//! [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778
314//!
315//! <br>
316//!
317//! # Builtin types
318//!
David Tolnay559fbb32020-03-17 23:32:20 -0700319//! In addition to all the primitive types (i32 &lt;=&gt; int32_t), the
320//! following common types may be used in the fields of shared structs and the
321//! arguments and returns of functions.
David Tolnay7db73692019-10-20 14:51:12 -0400322//!
323//! <table>
324//! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>
David Tolnay750755e2020-03-01 13:04:08 -0800325//! <tr><td>String</td><td>rust::String</td><td></td></tr>
326//! <tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>
David Tolnayefe81052020-04-14 16:28:24 -0700327//! <tr><td>&amp;[u8]</td><td>rust::Slice&lt;uint8_t&gt;</td><td><sup><i>arbitrary &amp;[T] not implemented yet</i></sup></td></tr>
David Tolnay7a9b1302020-04-24 16:15:22 -0700328//! <tr><td><a href="struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>
David Tolnay750755e2020-03-01 13:04:08 -0800329//! <tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
David Tolnay7a9b1302020-04-24 16:15:22 -0700330//! <tr><td><a href="struct.UniquePtr.html">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
David Tolnay347c3d02020-04-24 16:14:07 -0700331//! <tr><td>Vec&lt;T&gt;</td><td>rust::Vec&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
David Tolnaya8df0942020-04-25 19:08:40 -0700332//! <tr><td><a href="struct.CxxVector.html">CxxVector&lt;T&gt;</a></td><td>std::vector&lt;T&gt;</td><td><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>
David Tolnayaddc7482020-03-29 22:19:44 -0700333//! <tr><td>fn(T, U) -&gt; V</td><td>rust::Fn&lt;V(T, U)&gt;</td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>
David Tolnay31b5aad2020-04-10 19:35:47 -0700334//! <tr><td>Result&lt;T&gt;</td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr>
David Tolnay7db73692019-10-20 14:51:12 -0400335//! </table>
336//!
David Tolnay736cbca2020-03-11 16:49:18 -0700337//! The C++ API of the `rust` namespace is defined by the *include/cxx.h* file
David Tolnay7614e772020-11-10 22:55:40 -0800338//! in <https://github.com/dtolnay/cxx>. You will need to include this header in
David Tolnay736cbca2020-03-11 16:49:18 -0700339//! your C++ code when working with those types.
David Tolnay7db73692019-10-20 14:51:12 -0400340//!
341//! The following types are intended to be supported "soon" but are just not
342//! implemented yet. I don't expect any of these to be hard to make work but
343//! it's a matter of designing a nice API for each in its non-native language.
344//!
345//! <table>
346//! <tr><th>name in Rust</th><th>name in C++</th></tr>
David Tolnay84f232e2020-01-08 12:22:56 -0800347//! <tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
348//! <tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
David Tolnay239d05f2020-03-13 01:36:50 -0700349//! <tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
David Tolnay85487b02020-08-22 06:13:27 -0700350//! <tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
David Tolnay84f232e2020-01-08 12:22:56 -0800351//! <tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>
352//! <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>
David Tolnay239d05f2020-03-13 01:36:50 -0700353//! <tr><td><sup><i>tbd</i></sup></td><td>std::shared_ptr&lt;T&gt;</td></tr>
David Tolnay7db73692019-10-20 14:51:12 -0400354//! </table>
355
David Tolnayc5a52f92020-09-14 00:43:29 -0400356#![no_std]
David Tolnaya91ac382020-11-11 09:34:59 -0800357#![doc(html_root_url = "https://docs.rs/cxx/0.5.9")]
David Tolnay7db73692019-10-20 14:51:12 -0400358#![deny(improper_ctypes)]
David Tolnayc6ba2d22020-05-07 17:48:29 -0700359#![allow(non_camel_case_types)]
David Tolnay7db73692019-10-20 14:51:12 -0400360#![allow(
David Tolnay4bc98152020-04-09 23:24:01 -0700361 clippy::cognitive_complexity,
David Tolnayd2bb3da2020-03-18 17:19:39 -0700362 clippy::declare_interior_mutable_const,
David Tolnay30d214c2020-03-15 23:54:34 -0700363 clippy::inherent_to_string,
David Tolnay7db73692019-10-20 14:51:12 -0400364 clippy::large_enum_variant,
David Tolnayc79ba752020-05-05 10:13:00 -0700365 clippy::len_without_is_empty,
David Tolnay7db73692019-10-20 14:51:12 -0400366 clippy::missing_safety_doc,
367 clippy::module_inception,
David Tolnay30d214c2020-03-15 23:54:34 -0700368 clippy::needless_doctest_main,
David Tolnay7db73692019-10-20 14:51:12 -0400369 clippy::new_without_default,
370 clippy::or_fun_call,
371 clippy::ptr_arg,
372 clippy::toplevel_ref_arg,
David Tolnay7db73692019-10-20 14:51:12 -0400373 clippy::useless_let_if_seq
374)]
375
David Tolnay585a9fe2020-08-30 21:03:38 -0700376#[cfg(built_with_cargo)]
David Tolnayaf60e232020-01-24 15:22:09 -0800377extern crate link_cplusplus;
David Tolnay9f6c0752020-09-07 22:26:46 -0700378
David Tolnay3384c142020-09-14 00:26:47 -0400379extern crate alloc;
David Tolnayc5a52f92020-09-14 00:43:29 -0400380extern crate std;
David Tolnay3384c142020-09-14 00:26:47 -0400381
David Tolnayda5bd272020-03-16 21:53:22 -0700382#[macro_use]
David Tolnay9f6c0752020-09-07 22:26:46 -0700383mod macros;
David Tolnayda5bd272020-03-16 21:53:22 -0700384
David Tolnay7db73692019-10-20 14:51:12 -0400385mod cxx_string;
David Tolnaye90be1d2020-04-24 11:45:57 -0700386mod cxx_vector;
David Tolnayebef4a22020-03-17 15:33:47 -0700387mod exception;
David Tolnay5f9e8ca2020-05-07 17:21:05 -0700388mod extern_type;
David Tolnay75dca2e2020-03-25 20:17:52 -0700389mod function;
David Tolnay7db73692019-10-20 14:51:12 -0400390mod opaque;
David Tolnay486b6ec2020-03-17 01:19:57 -0700391mod result;
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700392mod rust_sliceu8;
David Tolnay7db73692019-10-20 14:51:12 -0400393mod rust_str;
394mod rust_string;
Myron Ahneba35cf2020-02-05 19:41:51 +0700395mod rust_vec;
David Tolnay9f6c0752020-09-07 22:26:46 -0700396mod symbols;
David Tolnay7db73692019-10-20 14:51:12 -0400397mod unique_ptr;
398mod unwind;
399
400pub use crate::cxx_string::CxxString;
David Tolnaye90be1d2020-04-24 11:45:57 -0700401pub use crate::cxx_vector::CxxVector;
David Tolnayebef4a22020-03-17 15:33:47 -0700402pub use crate::exception::Exception;
David Tolnay38f5ad62020-10-03 18:06:44 -0700403pub use crate::extern_type::{kind, ExternType};
David Tolnay7db73692019-10-20 14:51:12 -0400404pub use crate::unique_ptr::UniquePtr;
David Tolnay96c351b2020-05-08 13:06:18 -0700405pub use cxxbridge_macro::bridge;
David Tolnay094db3e2020-05-08 00:12:50 -0700406
407/// For use in impls of the `ExternType` trait. See [`ExternType`].
David Tolnay3cb75422020-08-27 23:40:43 -0700408///
409/// [`ExternType`]: trait.ExternType.html
David Tolnay094db3e2020-05-08 00:12:50 -0700410pub use cxxbridge_macro::type_id;
David Tolnay7db73692019-10-20 14:51:12 -0400411
David Tolnayf2eb3e72020-08-27 23:30:44 -0700412/// Synonym for `CxxString`.
413///
414/// To avoid confusion with Rust's standard library string you probably
415/// shouldn't import this type with `use`. Instead, write `cxx::String`, or
416/// import and use `CxxString`.
417pub type String = CxxString;
418
419/// Synonym for `CxxVector`.
420///
421/// To avoid confusion with Rust's standard library vector you probably
422/// shouldn't import this type with `use`. Instead, write `cxx::Vector<T>`, or
423/// import and use `CxxVector`.
424pub type Vector<T> = CxxVector<T>;
425
David Tolnay7db73692019-10-20 14:51:12 -0400426// Not public API.
427#[doc(hidden)]
428pub mod private {
David Tolnay67ba0b52020-04-24 12:43:39 -0700429 pub use crate::cxx_vector::VectorElement;
David Tolnay63a0e4e2020-10-03 18:52:32 -0700430 pub use crate::extern_type::{verify_extern_kind, verify_extern_type};
David Tolnay75dca2e2020-03-25 20:17:52 -0700431 pub use crate::function::FatFunction;
David Tolnay7db73692019-10-20 14:51:12 -0400432 pub use crate::opaque::Opaque;
David Tolnay486b6ec2020-03-17 01:19:57 -0700433 pub use crate::result::{r#try, Result};
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700434 pub use crate::rust_sliceu8::RustSliceU8;
David Tolnay7db73692019-10-20 14:51:12 -0400435 pub use crate::rust_str::RustStr;
436 pub use crate::rust_string::RustString;
David Tolnay6c6b7e02020-04-24 11:42:59 -0700437 pub use crate::rust_vec::RustVec;
David Tolnay7db73692019-10-20 14:51:12 -0400438 pub use crate::unique_ptr::UniquePtrTarget;
439 pub use crate::unwind::catch_unwind;
440}
David Tolnayc6ba2d22020-05-07 17:48:29 -0700441
442macro_rules! chars {
443 ($($ch:ident)*) => {
444 $(
445 #[doc(hidden)]
446 pub enum $ch {}
447 )*
448 };
449}
450
451chars! {
452 _0 _1 _2 _3 _4 _5 _6 _7 _8 _9
453 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
454 a b c d e f g h i j k l m n o p q r s t u v w x y z
455 __ // underscore
456}