How do you read a YAML file in Rust?
Asked Answered
F

3

27

I've poked the serde-yaml and yaml-rust crates a bit, but I haven't seen any examples.

Frascati answered 10/11, 2018 at 21:56 Comment(0)
A
36

serde-yaml's documentation has the following 4 functions:

  • from_reader — Deserialize an instance of type T from an IO stream of YAML.
  • from_slice — Deserialize an instance of type T from bytes of YAML text.
  • from_str — Deserialize an instance of type T from a string of YAML text.
  • from_value — Interpret a serde_yaml::Value as an instance of type T.

Using from_reader as an example:

use serde_yaml; // 0.8.7

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let f = std::fs::File::open("something.yaml")?;
    let d: String = serde_yaml::from_reader(f)?;
    println!("Read YAML string: {}", d);
    Ok(())
}

something.yaml:

"I am YAML"

You can deserialize into the looser-typed Value if you don't know your format (String in this example), but be sure to read the Serde guide for full details of how to do type-directed serialization and deserialization instead.

See also:

In general, using any Serde format is pretty much the same as all the rest.

Amanuensis answered 10/11, 2018 at 22:15 Comment(5)
This example returns Error: Scan(ScanError { mark: Marker { index: 7, line: 2, col: 4 }, info: "mapping values are not allowed in this context" }); does anything changed since your answer @Amanuensis ?Marcionism
@Marcionism sounds like your YAML file is malformed or doesn't match with the type that you are attempting to parse.Amanuensis
humm sorry (rust beginner here); i was more trying to parse key/value'd yaml file (a one liner like a: 'b' ) to get started). but i guess it goes well beyond the scope of the initial issue hereMarcionism
@Marcionism that's what "You can deserialize into the looser-typed Value if you don't know your format " and "read the Serde guide for full details of how to do type-directed" refer to.Amanuensis
For anyone reading this later on, the serde-yaml repository has been archived but there is an active fork that can be found here: github.com/sebastienrousseau/serde_ymlSirdar
M
14

This example uses the yaml_rust crate

use std::fs::File;
use std::io::prelude::*;
use yaml_rust::yaml::{Hash, Yaml};
use yaml_rust::YamlLoader;

fn main() {
    println!("Hello, Yaml");
    let file = "./etc/my_yaml_file.yaml";
    load_file(file);
}

fn load_file(file: &str) {
    let mut file = File::open(file).expect("Unable to open file");
    let mut contents = String::new();

    file.read_to_string(&mut contents)
        .expect("Unable to read file");

    let docs = YamlLoader::load_from_str(&contents).unwrap();

    // iterate / process doc[s] ..
}
Mazza answered 1/3, 2019 at 1:31 Comment(1)
Also consider std::fs::read_to_string to read the file contents.Underpart
E
4

The answer from Shepmaster is great if you want to do it properly. Here's a complete example to get started with.

data['foo']['bar'].as_str() returns an Option<str>.

fn example() -> Result<String> {
    let f = std::fs::File::open("something.yaml")?;
    let data: serde_yaml::Value = serde_yaml::from_reader(f)?;
    data["foo"]["bar"]
        .as_str()
        .map(|s| s.to_string())
        .ok_or(anyhow!("Could not find key foo.bar in something.yaml"))
}
Estefanaestel answered 18/11, 2020 at 1:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.