Recursive AI

Read YAML 1.1 files: yes, no and 0755

All oneyaml Rust recipes

In YAML 1.1, no is false (the “Norway problem”) and 0755 is octal. YAML 1.2 fixed both: no is a string and 0755 is the decimal 755. oneyaml reads YAML 1.2 by default; when a file was written for an older parser, turn on the YAML 1.1 behaviors you need.

RUST
use oneyaml::{Compat, Settings, Value};
 
fn main() -> Result<(), oneyaml::Error> {
    let src = "\
country: no
enabled: yes
mode: 0755
";
    // YAML 1.2 (the default): `no` and `yes` are strings, 0755 is 755.
    let v: Value = oneyaml::from_str(src)?;
    println!("1.2: {:?} {:?} {:?}", v["country"], v["enabled"], v["mode"]);
 
    // One YAML 1.1 behavior at a time...
    let v: Value = oneyaml::from_str_with(src, &Settings::new().yaml11_booleans(true))?;
    println!("1.1 booleans: {:?} {:?}", v["country"], v["enabled"]);
 
    // ...or all of them, as older YAML 1.1 parsers read the file.
    let v: Value = oneyaml::from_str_with(src, &Compat::yaml_1_1())?;
    println!("1.1: {:?} {:?} {:?}", v["country"], v["enabled"], v["mode"]);
    Ok(())
}
Text
1.2: String("no") String("yes") Number(755)
1.1 booleans: Bool(false) Bool(true)
1.1: Bool(false) Bool(true) Number(493)

Good to know

  • Each YAML 1.1 behavior is its own setting, off by default: yaml11_booleans, legacy_octal, sexagesimal, digit_separators, yaml11_int_forms and merge_keys.
  • Compat::yaml_1_1() turns them all on. Compat::serde_yaml() gets close to serde_yaml’s behavior, for a migration; the migration guide lists every difference.
  • A boolean field given yes under YAML 1.2 is an error whose help suggests writing true, with a fix you can apply (errors with line and column).
  • Quoted values are always strings: "no" is the string no under every setting.

Moving off serde_yaml: serde_yaml is deprecated: what now.

Why NO becomes false, and what nine YAML libraries do with it: The YAML Norway problem.