| # Rust API Design Principles | |
| This policy lays out guidelines for designing the user-facing parts of core Rust | |
| libraries in Chromium. It is meant to provide guidance on relative priorities | |
| to help decide between different possible designs. | |
| Note: These guidelines are aimed at _core_ Rust libraries (e.g. `//base`) which | |
| expect to see broad, general use across Chromium. They may or may not apply to | |
| code designed for more specialized parts of the codebase. Conversely, since | |
| these guidelines are aimed at libraries _in Chromium_, they have different | |
| considerations than the Rust standard library, which aims to support all | |
| possible use cases. | |
| These design principles are undergoing constant development; expect more to be | |
| added in the future. Existing guidelines should change only rarely. | |
| ## Core Design Goals | |
| The first of these goals is the most important; beyond that, these goals are not | |
| ordered. | |
| 1. APIs must promote the use of Rust in Chromium. If Chromium developers are | |
| unwilling to use an API (because it’s unergonomic, not performant, etc), then it | |
| is a bad design. | |
| 1. Therefore… | |
| 1. APIs should be performant, imposing as little runtime overhead as | |
| possible. | |
| 1. APIs should be ergonomic, requiring as little boilerplate as possible. | |
| 1. APIs should be idiomatic Rust, to make it easy for Rust developers to | |
| use it, and for C++ developers to familiarize themselves with Rust. | |
| 1. APIs should minimize the potential for misuse, especially misuse with | |
| security implications (such as undefined behavior). | |
| ## Compatibility with the Generic Rust Guidelines | |
| 1. APIs should follow the | |
| [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/) | |
| ## (Un)Safety | |
| 1. APIs should not require users to use `unsafe` code if at all possible. | |
| 1. This includes `unsafe` functions, as well as those that require `unsafe` | |
| in order to use the result (e.g. by returning a raw pointer). | |
| 1. Examples of exceptions are code that imposes such a large performance hit | |
| that it’s deemed unacceptable to use, or that requires patterns that are | |
| annoying enough that developers will try to avoid using them. | |
| 1. If we provide an `unsafe` API, we should try to provide an equivalent safe | |
| API and encourage its use when possible. | |
| 1. _Internal_ use of `unsafe` is acceptable, so long it is encapsulated and | |
| not exposed to the user, and there isn’t an easy safe alternative. | |
| ## C/C++ Interop via FFI | |
| Chromium has three options available for interoperation with C and C++: | |
| 1. Bindgen: Automatically generates bindings for C code. Supported by the Rust | |
| maintainers. | |
| 1. Cxx: Generates user-specified bindings to C++ code. A | |
| [third-party crate](https://cxx.rs/) with minimal new feature development. | |
| 1. Crubit: Automatically generates bindings. Supported in Chromium for calling | |
| Rust from C++ in most directories (except where Cronet support is required). | |
| Support for the reverse direction (calling C++ from Rust) is under development. | |
| For more information, see [ffi.md](/docs/rust/ffi.md). In the long run, we | |
| prefer Crubit, but since it is not yet universally available or fully integrated, | |
| we recommend Cxx for now. | |
| Therefore, these guidelines aim to minimize the migration cost from Cxx to | |
| Crubit in the future. | |
| 1. For C bindings, use bindgen. | |
| 1. For C++ bindings, use Crubit if possible, and Cxx otherwise. | |
| 1. Wrap FFI functions in safe, idiomatic Rust APIs. | |
| 1. When using Cxx, keep APIs minimal, to minimize the surface area of a future | |
| migration to Crubit. |