how to parse a YAML containing a simple list together with a key-value list (associative array)

落爺英雄遲暮 提交于 2021-02-05 11:52:03

问题


I have the following YAML:

build:
  - step 1
  - step 2

  - name: step 3
    do: something

  - name: step 4
    get: fetch ...

  - name: step 5
    put: upload something

And for parsing it I am trying with this

#[derive(Debug, Deserialize, PartialEq)] 
struct Config {
  build: Option<Vec<Steps>>
}

#[derive(Debug, Deserialize, PartialEq)]
struct Build {
    #[serde(flatten)]
    item: String,
    steps: Steps,
}

#[derive(Debug, Deserialize, PartialEq)]
struct Steps {
    name: String,
    r#do: Option<String>,
    put: Option<String>,
    get: Option<String>,
}

But I get this error:

Error parsing configuration file: build[0]: invalid type: string "step 1", expected struct Build

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0ddb0eb8be0888e74b089eb0ebc5daee

I do can parse only:

build:
 - step 1
 - step 2

Using this:

#[derive(Debug, Deserialize, PartialEq)]
struct Config {
   build: Option<Vec<String>>
}

Or:

 build:
 - name: step 1
   do: foo
 - name: step 2
   do: bar

Using:

#[derive(Debug, Deserialize, PartialEq)]
struct Config {
   build: Option<Vec<Steps>>
} 

But can't find a way to have both options, any idea about how could this be parsed?


回答1:


Use an enum:

#[derive(Debug, serde::Deserialize, PartialEq)]
struct Build {
    build: Vec<Foo>,
}

#[derive(Debug, serde::Deserialize, PartialEq)]
#[serde(untagged)]
enum Foo {
    Step(Step),
    Bar(String),
}

#[derive(Debug, serde::Deserialize, PartialEq)]
struct Step {
    name: String,
    #[serde(rename = "do")]
    make: Option<String>,
    put: Option<String>,
    get: Option<String>,
}

fn main() -> Result<(), serde_yaml::Error> {
    let input = r#"build:
  - step 1
  - step 2

  - name: step 3
    do: something

  - name: step 4
    get: fetch ...

  - name: step 5
    put: upload something"#;

    let build: Build = serde_yaml::from_str(input)?;

    println!("{:#?}", build);

    Ok(())
}


来源:https://stackoverflow.com/questions/61793475/how-to-parse-a-yaml-containing-a-simple-list-together-with-a-key-value-list-ass

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!