Warning
Depending on how this crate is received, this crate may continue development and the API may change between releases. If you use it today, please pin a commit or version and expect some breaking updates.
This workspace provides Rust bindings to the libdnf5 C++ library so your Rust code can interact with DNF's functionalities in a safe, ergonomic way. The bindings hide the unsafe C++ details behind a small set of helper C++ functions and a clean Rust facade.
- The low-level FFI layer is implemented with the
cxxcrate: small C++ helper functions (inlibdnf5/srcandlibdnf5/include) expose the functionality we need from libdnf5 to Rust. - The Rust side (in
libdnf5/src/lib.rsandlibdnf5/src/bridge.rs) wraps thosecxxbindings with safe, idiomatic types and methods (Context, RepoSack, Package, PackageSet, Transaction, etc.). - API documentation is generated from the Rust docs and is the canonical reference for the Rust API.
- Rust and Cargo
- A C++ toolchain capable of compiling the C++ helper sources (g++ or clang++)
- libdnf5 installed on your system and discoverable via
pkg-config. See installation at the official libdnf5 documentation. If libdnf5 is installed in a non-standard path, ensurePKG_CONFIG_PATHor the compiler include/library paths are adjusted appropriately.
Generating the Rust API docs
To generate the Rust API docs for the bindings run:
cargo doc -p libdnf5 --no-deps
The generated docs are the API reference listing methods, types, and doc comments produced from the Rust facade (for example, libdnf5/src/lib.rs). We will keep libdnf5/src/lib.rs docs up to date as the API evolves.
This repository is a Cargo workspace. From the repo root you can build individual crates or the whole workspace:
cargo build # builds workspace
cargo build -p libdnf5 # build the bindings crate
There are small example crates in this workspace:
demo/— basic usage examples and a small runnable demodnf/— cli tool that implements the libdnf5 rust bindings
- We call into libdnf5's C++ API from small helper functions written in C++.
- Those helper functions are exposed to Rust using the
cxxcrate and a small bridge module (libdnf5/src/bridge.rs). - A safe Rust facade (
libdnf5/src/lib.rs) wraps thecxxtypes and presents idiomatic Rust types (Context, RepoSack, Package, PackageSet, Transaction, etc.) that perform checks and convert error cases intoanyhow::Result.
Where to look in the repo
libdnf5/include/: C++ header helpers for the FFI layer (C++ declarations used by the bridge)libdnf5/src/: C++ helper implementations and Rust facade/bridge codelibdnf5/src/bridge.rs:cxxbridge definitionslibdnf5/src/lib.rs: high-level Rust API (what you will call from Rust code)
demo/,dnf/: example binariesrepo_samples/: sample repo files used by demos/tests
- The facade methods return
anyhow::Resultand try to surface meaningful errors when the underlying C++ call fails. - Many methods accept &str inputs and return owned Rust types (String, Vec, etc.) to make usage ergonomic.
We welcome those looking to contribute, but we are particular!
- If you add new C++ helpers, update the
bridge.rscxxinterface and add safe Rust wrappers inlib.rs. - Keep public Rust API docs updated — they are the primary developer reference and are what
cargo docgenerates.
This project builds on libdnf5 and cxx and the work of the DNF/libdnf community. The bindings exist to make that functionality accessible from Rust while keeping the unsafe surface minimal.
Check out: