As part of the Rust Digger project I wanted to read the Cargo.toml file that comes with the project. At first I tried the read_manifest method of the Cargo crate, but I could not figure out how to use it.
Luckily then I encountered the cargo_toml crate that provides a much easier way to get started.
Dependencies
examples/read-cargo-toml/Cargo.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
The code:
examples/read-cargo-toml/src/main.rs
use cargo_toml::{Edition, Manifest};
fn main() {
for filename in vec![
"Cargo_only_edition.toml",
"Cargo_only_version.toml",
"Cargo_both_edition_and_version.toml",
"Cargo_neither.toml",
] {
println!("{filename}");
let manifest = std::fs::read_to_string(filename).unwrap();
let cargo_toml = Manifest::from_str(&manifest).unwrap();
//println!("{cargo_toml:?}");
match cargo_toml.package().rust_version() {
Some(rust_version) => println!("{rust_version}"),
None => println!("No rust-version"),
}
let edition = cargo_toml.package().edition();
let year = match edition {
Edition::E2015 => "2015",
Edition::E2018 => "2018",
Edition::E2021 => "2021",
};
println!("edition {year}");
println!("------");
}
let filename = "Cargo_invalid_field.toml";
let manifest = std::fs::read_to_string(filename).unwrap();
let cargo_toml = Manifest::from_str(&manifest).unwrap();
println!("{:#?}", cargo_toml);
}
My current interests are the edition
and the rust-version
fields as I am working on the
issue of MSRV (Minimum Supported Rust Version) indication.
Two observations:
-
The
Edition
field will default to 2015. -
IF there are invalid fields they are disregarded.
The various sample input files:
examples/read-cargo-toml/Cargo_only_edition.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
examples/read-cargo-toml/Cargo_only_version.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
rust-version = "1.77"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
examples/read-cargo-toml/Cargo_both_edition_and_version.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
edition = "2021"
rust-version = "1.77"
invalid-field = "invalid value"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
examples/read-cargo-toml/Cargo_neither.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
examples/read-cargo-toml/Cargo_invalid_field.toml
[package]
name = "read-cargo-toml"
version = "0.1.0"
edition = "2021"
invalid_field = "invalid value"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cargo_toml = "0.19.2"
The output:
Cargo_only_edition.toml
No rust-version
edition 2021
------
Cargo_only_version.toml
1.77
edition 2015
------
Cargo_both_edition_and_version.toml
1.77
edition 2021
------
Cargo_neither.toml
No rust-version
edition 2015
------
Manifest {
package: Some(
Package {
name: "read-cargo-toml",
edition: Set(
E2021,
),
rust_version: None,
version: Set(
"0.1.0",
),
build: None,
workspace: None,
authors: Set(
[],
),
links: None,
description: None,
homepage: None,
documentation: None,
readme: Set(
Flag(
true,
),
),
keywords: Set(
[],
),
categories: Set(
[],
),
exclude: Set(
[],
),
include: Set(
[],
),
license: None,
license_file: None,
repository: None,
default_run: None,
autobins: true,
autoexamples: true,
autotests: true,
autobenches: true,
publish: Set(
Flag(
true,
),
),
resolver: None,
metadata: None,
},
),
workspace: None,
dependencies: {
"cargo_toml": Simple(
"0.19.2",
),
},
dev_dependencies: {},
build_dependencies: {},
target: {},
features: {},
replace: {},
patch: {},
lib: None,
profile: Profiles {
release: None,
dev: None,
test: None,
bench: None,
doc: None,
custom: {},
},
badges: Badges {
appveyor: None,
circle_ci: None,
gitlab: None,
travis_ci: None,
codecov: None,
coveralls: None,
is_it_maintained_issue_resolution: None,
is_it_maintained_open_issues: None,
maintenance: Maintenance {
status: None,
},
},
bin: [],
bench: [],
test: [],
example: [],
lints: None,
}