| # C++ bindings for Rust traits | |
| Crubit allows C++ callers to invoke Rust trait implementations. For each `trait | |
| SomeTrait`, Crubit generates a matching C++ `struct SomeTrait`. To call a trait | |
| method `SomeTrait::some_fn` implemented by `SomeType`, C++ callers can use | |
| `SomeTrait::impl<SomeType>::some_fn(args...)`. | |
| ## Example | |
| Given the following Rust crate: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/example.rs | |
| ``` | |
| You can call the trait from C++ using the following code: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/main.cc function:main | |
| ``` | |
| Each trait has an associated `impl` member which is generic upon the `Self` type | |
| of the trait implementation, and which provides all of the associated types, | |
| consts, and functions. | |
| ## Checking if a trait is implemented | |
| C++ users can check if a trait implementation is available using `rs::where_v<T, | |
| SomeTrait>`. This is useful when writing templated C++ functions, as it can be | |
| used with `requires` (or `enable_if`) to specify that a particular trait is | |
| implemented by a type parameter. For example: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/main.cc function:add_with_2 | |
| ``` | |
| ## Limitations | |
| Some trait implementations will not receive bindings: | |
| * Trait implementations with generic parameters (e.g. `impl<T> ...`) will not | |
| receive bindings. | |
| * For example, an implementation `impl<U> TwoArgs<i32, U> for MyStruct` | |
| will not receive bindings because the `impl` has a type parameter (`U`). | |
| * This also means that blanket impls (e.g. `impl<T> Trait for T`) are not | |
| supported. | |
| * Traits with `const` parameters (e.g. `trait T<const V: usize>`) do not yet | |
| receive bindings. | |
| * Trait methods will not receive bindings if their parameter or return types | |
| are not yet supported by Crubit. | |
| ## How does it work? | |
| Under the hood, Crubit will generate three bindings from the example Rust crate. | |
| A template specialization for `impl MyTrait for MyStruct`: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/example_generated.h class:impl | |
| ``` | |
| Our generated `rs::impl` specialization is an implementation detail of binding | |
| generation. It holds the actual thunks that call into rust to implement our | |
| trait, but they should be accessed through our template struct `MyTrait`: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/example_generated.h class:MyTrait | |
| ``` | |
| Each struct generated for a Rust trait has the `impl` member that provides | |
| access to the generated `rs::impl`. This is the preferred way to reference the | |
| generated `rs::impl`. | |
| Finally, a struct for `MyStruct`: | |
| ```live-snippet | |
| cs/file:examples/rust/trait/example_generated.h class:MyStruct | |
| ``` | |
| Our struct is generated normally and exists purely so we have something to | |
| implement our trait for. |