# Rust in WebRTC ## Current status WebRTC is adopting [Rust] to advance memory safety. Rust targets and build infrastructure have been integrated into the repository and are enabled by default. Currently there are few Rust component integrated into tests, but not production code. As a next step we plan to integrate a small Rust component into production code, but keep a c++ fallback. ## rtc_rust build flag Rust support is controlled by the GN build argument `rtc_rust` in `webrtc.gni`: ```gn # Enables or disables Rust targets in WebRTC. rtc_rust = true ``` C++ code can check if Rust is enabled by checking `WEBRTC_WITHOUT_RUST` define. We plan to eventually remove the `rtc_rust` build flag and `WEBRTC_WITHOUT_RUST` define and require all downstream builds to provide a working Rust toolchain. ## GN Templates - **`rtc_rust_library`**: Defines a Rust static library. - **`rtc_rust_cxx_bridge`**: Defines a single-source C++/Rust FFI bridge using the [CXX] crate. - **`rtc_rust_unittest`**: Defines a single Rust unit test binary. - **`rtc_rust_test_suite`**: Aggregates multiple Rust unit test targets into a test suite group. ## Style guide With few exceptions, WebRTC follows [Chromium Rust Style guide][rust-chromium-style-guide], which in turn follows [Rust Style Guide][rust-style-guide] and [Rust API Guidelines][rust-api-guide]. ### Use webrtc::import! macro ```rust webrtc::import! { // Crates can be imported using their target name (e.g. `time_delta_rs`): "//api/unit:time_delta_rs"; // Target names can be overridden for brevity: "//modules/rtp_rtcp:corruption_detection_extension" as cde; } ``` ### Use Rust standard test framework See [Rust Book][rust-test] for the guidance. Support for [Chromium's test framework][rust-chromium-test] or [Googles test framework][rust-google-test] is currently not implemented. ## C++/Rust Interoperability Interoperability between C++ and Rust is handled through the [CXX] crate. We plan to switch to [Crubit] when its support will be implemented in more environments, in particular when it will be fully [supported][crubit-in-chromium-issue] by chromium infrastructure. FFI bindings are declared in Rust source files using `#[cxx::bridge]`. Use C++ namespace `webrtc` for all bindings. Declare bindings in Rust mod `ffi`. **Examples:** ```rust // bindings to call C++ from Rust #[cxx::bridge(namespace = "webrtc")] mod ffi { unsafe extern "C++" { include!("path/to/a_cpp_library.h"); fn CppFunction(value: i32) -> i64; } } pub fn cpp_function(value: i32) -> i64 { ffi::CppFunction(value) } ``` ```rust // bindings to call Rust from C++ webrtc::import! { "//path/to/rust:a_rust_library"; } use a_rust_library::rust_function; #[cxx::bridge(namespace = "webrtc")] mod ffi { extern "Rust" { fn rust_function(value: i64) -> u64; } } ``` ```gn import("../../webrtc.gni") rtc_library("cpp_only_library") { sources = [ "cpp_only_library.cc", "cpp_only_library.h", ] } if (rtc_rust) { rtc_rust_cxx_bridge("call_cpp_from_rust_cxx") { allow_unsafe = true source = "call_cpp_from_rust_cxx.rs" deps = [ ":cpp_only_library", "//build/rust:cxx_rustdeps", ] } rtc_rust_library("my_rust_feature") { crate_root = "my_rust_feature.rs" sources = [ "my_rust_feature.rs" ] deps = [ ":call_cpp_from_rust_cxx", ] } rtc_rust_unittest("my_rust_feature_test") { crate_root = "my_rust_feature.rs" sources = [ "my_rust_feature.rs" ] deps = [ ":call_cpp_from_rust_cxx", ] } rtc_rust_cxx_bridge("call_rust_from_cpp_cxx") { allow_unsafe = true source = "call_rust_from_cpp_cxx.rs" deps = [ ":my_rust_feature", "//build/rust:cxx_rustdeps", ] } } rtc_library("cpp_maybe_use_rust") { sources = [ "cpp_maybe_use_rust.cc" ] deps = [...] if (rtc_rust) { deps += [":call_rust_from_cpp_cxx"] } } ``` ```cpp // cpp_maybe_use_rust.cc #ifndef WEBRTC_WITHOUT_RUST #include "call_rust_from_cpp_cxx.rs.h" #endif ... uint64_t MaybeUseRust(int64_t value) { #ifdef WEBRTC_WITHOUT_RUST return CallCppFallback(value); #else return rust_function(value); #endif } ``` [crubit]: http://crubit.rs/ [crubit-in-chromium-issue]: http://crbug.com/351793625 [cxx]: http://cxx.rs/ [rust]: https://rust-lang.org/ [rust-api-guide]: https://rust-lang.github.io/api-guidelines/ [rust-chromium-style-guide]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/rust/rust.md [rust-chromium-test]: https://source.chromium.org/chromium/chromium/src/+/main:testing/rust_gtest_interop/ [rust-google-test]: https://github.com/google/googletest-rust [rust-style-guide]: https://doc.rust-lang.org/style-guide/ [rust-test]: https://doc.rust-lang.org/book/ch11-01-writing-tests.html