Bitflags in Rust
While working on Rust bindings for KConfig as a part of Season of KDE 2022, I came across a few problems while trying to represent
QFlags in Rust:
QFlagsare defined as C++ enums in which multiple members can have the same value. This is not possible in Rust enum.
- It is possible to enable multiple flags using BitwiseOr. Rust enums cannot do bitwise operations.
This post will guide you through the various implementations I came up with and their tradeoffs.
The enum I was trying to implement was
KConfig::OpenFlags. The enum is given below:
This method uses a combination of Rust modules and consants. The sample implementation is as follow:
Const is replaced at compile time, so no performance cost.
All values can be documented in the same way using Rust comments.
Multiple flags can be activated.
- Not an enum. Just a collection of constants.
This method defines the problematic members as
impl. The sample implementation is as follows:
- Enum, for the most part.
- Inconsistent documentation. The constants don’t show up as enum variants.
- Multiple flags cannot be activated
This method uses standard rust enums. The sample implementation is as follows:
Documentation works as expected.
Function call every time passing from Rust to C++. I don’t think this will have much performance penalty, but still worth mentioning.
Cannot set multiple flags at once. Eg
OpenFlag::IncludeGlobal | OpenFlag::CascadeConfignot possible
Implementation 4: use bitflags crate
This is the implementation that I finally settled on. The implementation is as follows:
Multiple flags can be used together.
Documentation is consistent.
- Not enum. Shows up as