Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting started

Install, parse YAML into your own types, and emit it back. About five minutes.

Snippets below elide the enclosing function and use ?; assume each runs in a function returning saneyaml::Result<()>.

Install

[dependencies]
saneyaml = "0.3.0"
serde = { version = "1", features = ["derive"] }

Pure Rust, no C bindings, #![forbid(unsafe_code)]. MSRV 1.88.

Parse into a struct

The common case — load a config straight into your own types with #[derive(Deserialize)]:

#![allow(unused)]
fn main() {
use serde::Deserialize;

#[derive(Deserialize)]
struct Config {
    name: String,
    port: u16,
    tags: Vec<String>,
}

let cfg: Config = saneyaml::from_str("\
name: web
port: 8080
tags: [http, public]
")?;

assert_eq!(cfg.port, 8080);
assert_eq!(cfg.tags, ["http", "public"]);
}

Three entry points, same behavior — pick by what you hold:

#![allow(unused)]
fn main() {
let a: Config = saneyaml::from_str(text)?;     // &str
let b: Config = saneyaml::from_slice(bytes)?;  // &[u8]
let c: Config = saneyaml::from_reader(file)?;  // impl std::io::Read
}

Parse into a dynamic value

When you don’t know the shape ahead of time, deserialize into Value and walk it:

#![allow(unused)]
fn main() {
let v: saneyaml::Value = saneyaml::from_str("name: web\nport: 8080\n")?;

assert_eq!(v["name"].as_str(), Some("web"));
assert_eq!(v["port"].as_u64(), Some(8080));
}

Value mirrors serde_yaml::Value: as_str, as_i64, as_bool, as_sequence, as_mapping, indexing by key or position, and get for a non-panicking lookup. See the Cookbook for mutation and patching.

Emit

Serialize any Serialize value to YAML:

#![allow(unused)]
fn main() {
use serde::Serialize;

#[derive(Serialize)]
struct Config { name: String, port: u16 }

let cfg = Config { name: "web".into(), port: 8080 };

let text = saneyaml::to_string(&cfg)?;         // -> String
// name: web
// port: 8080

saneyaml::to_writer(std::io::stdout(), &cfg)?; // writes to any impl std::io::Write
}

The default writer produces clean, deterministic YAML. To tune layout — sort keys, force quoting, flow vs block — use EmitOptions and to_string_with_options; see the Cookbook.

Entry-point cheat sheet

You have…You want…Call
&str / &[u8] / readerone typed valuefrom_str / from_slice / from_reader
a multi-document streama Vec<T>from_documents_str / _slice / _reader
a multi-document streamone document at a timeDeserializer::from_str(...), then iterate
a Serialize valuea String or writerto_string / to_writer
YAML textthe raw structureparse_strNode, or read into Value
non-default schema or limitsany of the aboveLoadOptions::…().from_str(...)

Where to next