In Rust, through Cargo package management and build tools, you can conveniently manage project dependencies and metadata. Metadata is typically stored in the project's Cargo.toml file, which records information such as the package name, version, author, and dependencies.
However, the Rust standard library does not directly provide functionality to read metadata from Cargo.toml. If you wish to obtain this metadata at runtime, several approaches are available:
1. Using the built crate
The built crate is a tool that collects information during the build process and stores it as Rust code, making this information available in the compiled program. With this library, you can obtain details such as the version number, build time, and dependency versions.
How to use:
-
Add
builtas a dependency inCargo.toml, and also add it tobuild-dependencies:toml[dependencies] built = "0.5" [build-dependencies] built = "0.5" -
Create a build script in
build.rs:rustextern crate built; fn main() { built::write_built_file().expect("Failed to acquire build-time information"); } -
In your application code, you can access this information by including the generated
built.rsfile:rustmod built_info { include!(concat!(env!("OUT_DIR"), "/built.rs")); } fn main() { println!("This is version {}", built_info::PKG_VERSION); }
2. Manually parsing Cargo.toml into Rust code
By writing a build script build.rs, you can manually parse the Cargo.toml file and generate the required metadata as code into the output directory. This typically involves reading and parsing the TOML file to produce Rust code.
Steps:
-
Add
tomlandserdeas dependencies inCargo.toml:toml[dependencies] toml = "0.5" serde = { version = "1.0", features = ["derive"] } -
Write a
build.rsscript to parseCargo.tomland generate Rust code:rustuse std::fs::File; use std::io::Read; use std::path::Path; use toml::Value; fn main() { let mut file = File::open("Cargo.toml").unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); let toml = contents.parse::<Value>().unwrap(); let version = &toml["package"]["version"]; println!("cargo:rustc-env=VERSION={}", version); } -
In your Rust main program, you can access these values via environment variables:
rustfn main() { println!("Version: {}", env!("VERSION")); }
With these two approaches, you can access and utilize the metadata from Cargo packages within your Rust program.