1

I have the following YAML file

version: '3'
indexed:
  file1: "abc"
  file2: "def"
  file3: 33

I read it with this code:

pub fn read_conf() -> Result<(), Box<dyn Error>>{
    let f = File::open(".\\src\\conf.yaml")?;
    let d: Mapping = from_reader(f)?;
    let value = d.get(&Value::String("version".into())).unwrap();
    println!("{:?}", value.as_str().unwrap());

    let value = d.get(&Value::String("indexed.file1".into())).unwrap();
    println!("{:?}", value);
    Ok(())
}

which yields

"3"
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\libcore\option.rs:345:21

How do I instantiate Value to get the needed value?

freefall
  • 597
  • 2
  • 12
  • 28
  • Ok, my bad. I havent' asked any questions for a while and also it's my first question regarding Rust. Anyway I will keep that in mind. – freefall Jun 25 '19 at 15:26

1 Answers1

1

Use chained indexing syntax:

use serde_yaml::Value; // 0.8.9

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input = r#"
    version: '3'
    indexed:
      file1: "abc"
      file2: "def"
      file3: 33
    "#;

    let d: Value = serde_yaml::from_str(input)?;

    let f1 = &d["indexed"]["file1"];
    println!("{:?}", f1);

    Ok(())
}

Or better, derive Deserialize for a type and let it do the hard work:

use serde::Deserialize; // 1.0.93
use serde_yaml; // 0.8.9
use std::collections::BTreeMap;

#[derive(Debug, Deserialize)]
struct File {
    version: String,
    indexed: BTreeMap<String, String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input = r#"
    version: '3'
    indexed:
      file1: "abc"
      file2: "def"
      file3: 33
    "#;

    let file: File = serde_yaml::from_str(input)?;
    let f1 = &file.indexed["file1"];

    println!("{:?}", f1);

    Ok(())
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366