Как получить вложенное свойство из serde_yaml :: Value? - PullRequest
0 голосов
/ 25 июня 2019

У меня есть следующий файл YAML

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

Я прочитал это с этим кодом:

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(())
}

, что дает

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

Как мне создать экземпляр Value, чтобы получить необходимое значение?

1 Ответ

1 голос
/ 25 июня 2019

Использовать цепной индексный синтаксис:

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(())
}

Или, лучше, выведите Deserialize для типа и дайте ему выполнить тяжелую работу:

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(())
}

Смотри также:

...