zeenix / tomling

A simple TOML parser Rust crate
MIT License
1 stars 1 forks source link

tomling

Build Status API Documentation crates.io

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.

Usage

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"

"#;

Dependencies

Features

All features are enabled by default.

Comparison with toml crate

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.

Goals

Non-goals

License

MIT

The Name

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.