tomling is a simple TOML parser API, that is designed to have minimal dependencies and is no_std
compatible. The main target is Cargo manifests (Cargo.toml files) and hence why specific
API is provided for that purpose as well.
use tomling::{
cargo::{BuildDependency, Dependency, Manifest, ResolverVersion, RustEdition},
Value, parse,
};
//
// Using the `Cargo.toml` specific API:
//
let manifest: Manifest = tomling::from_str(CARGO_TOML).unwrap();
assert_eq!(manifest.package().name(), "example");
assert_eq!(manifest.package().version(), "0.1.0");
assert_eq!(manifest.package().edition().unwrap(), RustEdition::E2021);
assert_eq!(manifest.package().resolver().unwrap(), ResolverVersion::V2);
let authors = manifest.package().authors().unwrap();
let alice = &authors[0];
assert_eq!(alice.name(), "Alice Great");
assert_eq!(alice.email(), Some("foo@bar.com"));
let bob = &authors[1];
assert_eq!(bob.name(), "Bob Less");
assert_eq!(bob.email(), None);
let serde = match manifest.dependencies().unwrap().by_name("serde").unwrap() {
Dependency::Full(serde) => serde,
_ => panic!(),
};
assert_eq!(serde.version(), "1.0");
assert_eq!(serde.features(), Some(&["std", "derive"][..]));
let regex = match manifest.dependencies().unwrap().by_name("regex").unwrap() {
Dependency::VersionOnly(regex) => *regex,
_ => panic!(),
};
assert_eq!(regex, "1.5");
let cc = match manifest
.targets()
.unwrap()
.by_name("cfg(unix)")
.unwrap()
.build_dependencies()
.unwrap()
.by_name("cc")
.unwrap()
{
BuildDependency::VersionOnly(cc) => *cc,
_ => panic!(),
};
assert_eq!(cc, "1.0.3");
let default = manifest.features().unwrap().by_name("default").unwrap();
assert_eq!(default, &["serde"]);
let binary = &manifest.binaries().unwrap()[0];
assert_eq!(binary.name(), "some-binary");
assert_eq!(binary.path(), Some("src/bin/my-binary.rs"));
//
// Using the generic raw `TOML` parsing API:
//
let manifest = parse(CARGO_TOML).unwrap();
let package = match manifest.get("package").unwrap() {
Value::Table(package) => package,
_ => panic!(),
};
assert_eq!(package.get("name").unwrap(), &Value::String("example"));
assert_eq!(package.get("version").unwrap(), &Value::String("0.1.0"));
assert_eq!(package.get("edition").unwrap(), &Value::String("2021"));
assert_eq!(package.get("resolver").unwrap(), &Value::String("2"));
let deps = match manifest.get("dependencies").unwrap() {
Value::Table(deps) => deps,
_ => panic!(),
};
let serde = match deps.get("serde").unwrap() {
Value::Table(serde) => serde,
_ => panic!(),
};
assert_eq!(serde.get("version").unwrap(), &Value::String("1.0"));
let serde_features = match serde.get("features").unwrap() {
Value::Array(features) => features.as_slice(),
_ => panic!(),
};
assert_eq!(serde_features, &[Value::String("std"), Value::String("derive")]);
let regex = match deps.get("regex").unwrap() {
Value::String(regex) => *regex,
_ => panic!(),
};
assert_eq!(regex, "1.5");
const CARGO_TOML: &'static str = r#"
[package]
name = "example"
version = "0.1.0"
edition = "2021"
authors = ["Alice Great <foo@bar.com>", "Bob Less"]
resolver = "2"
[dependencies]
serde = { version = "1.0", features = [
"std",
"derive", # and here.
] }
regex = "1.5"
[target.'cfg(unix)'.build-dependencies]
cc = "1.0.3"
[features]
default = ["serde"]
[[bin]]
name = "some-binary"
path = "src/bin/my-binary.rs"
"#;winnowwithallocandsimdfeatures enabled.serde(optional) withallocandderivefeatures enabled.
serde- Enables Serde support.cargo-toml- Enables Cargo manifest specific API. This requiresserde.simd- Enables thesimdfeature ofwinnowfor SIMD acceleration for parsing.std- Enables some features, likestd::error::Errorimplementation forErrortype. It also enablesstdfeature ofwinnowandserde.
All features are enabled by default.
The toml crate is great but it being based on toml-edit, it ends up requiring indexmap crate
and its dependencies. tomling was created specifically to avoid most of these dependencies by
focusing completely on the parsing of TOML documents only.
- Simple parser/deserializer API.
- Minimum dependencies. The only mandatory dependency is
winnowwith only 2 features enabled. - Primary target: Cargo manifests.
- Strict compliance with the specification. This can change if sufficient demand arises. 😉
- Encoder/Serializer API.
The name "tomling" is a portmanteau of "TOML" and "ling" (a suffix meaning "a small thing"). Coincidentally, it also means a "male kitten" in English, with all the stress on the "kitten" part 😸 and none on the "male" part.