Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Parsing Yaml file

For the last 3 days now, I tried to figure out how to parse my yaml in Rust.
And I can’t figure out why it doesn’t work.

My Yaml:

default_verbosity: 0
logging:
  use_color: True,
  log_color: 
    fatal: Red,
    error: Red,
    warn: Red,
    info: Green,
    debug: Blue,
    trace: Yellow
  log_output: file,
  file_location: "example.log"
rocket: 
  mount_location: "/",
  port: 8000

But my programm failes at the unwrap line: let myYaml: Config = serde_yaml::from_reader(yamlFile).unwrap(); with this error message:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: 
Scan(ScanError { mark: Marker { index: 284, line: 14, col: 21 }, info: "while parsing 
a block mapping, did not find expected key" })', src/main.rs:41:60

My program:

use std::fs::File;

extern crate serde_yaml;

#[macro_use]
extern crate serde_derive;

#[derive(Debug, Serialize, Deserialize)]
struct ColorStruct {
    fatal: String,
    error: String,
    warn:  String,
    info:  String,
    debug: String,
    trace: String   
}

#[derive(Debug, Serialize, Deserialize)]
struct LoggingStruct {
    use_color:     bool,
    log_color:     Vec<ColorStruct>,
    log_output:    String,
    file_location: String 
}

#[derive(Debug, Serialize, Deserialize)]
struct RocketStruct {
    mount_location: String,
    port:          String
}

#[derive(Debug, Serialize, Deserialize)]
struct Config {
    default_verbosity: i32,
    logging:           Vec<LoggingStruct>,
    rocket:            Vec<RocketStruct>
}

fn main(){
    let yamlFile = File::open("config.yaml").unwrap();
    let myYaml: Config = serde_yaml::from_reader(yamlFile).unwrap();
}

I am really frustrated by this. What am I doing wrong? Am I missing something in my structs?

>Solution :

Both your schema and your yaml were wrong. Main reasons:

  • You should have nested structs, not Vec.
  • Your yaml types were not accurate, for example True is string, true is bool. 8000 is not String, "8000" is.
use std::fs::File;
use serde_yaml; // 0.8.23
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]
struct ColorStruct {
    fatal: String,
    error: String,
    warn:  String,
    info:  String,
    debug: String,
    trace: String   
}

#[derive(Debug, Serialize, Deserialize)]
struct LoggingStruct {
    use_color:     bool,
    log_color:     ColorStruct,
    log_output:    String,
    file_location: String 
}

#[derive(Debug, Serialize, Deserialize)]
struct RocketStruct {
    mount_location: String,
    port:          String
}

#[derive(Debug, Serialize, Deserialize)]
struct Config {
    default_verbosity: i32,
    logging:           LoggingStruct,
    rocket:            RocketStruct
}

fn main(){
    let yamlFile = r#"default_verbosity: 0
logging:
  use_color: true
  log_color: 
    fatal: "Red"
    error: "Red"
    warn: "Red"
    info: "Green"
    debug: "Blue"
    trace: "Yellow"
  log_output: "file"
  file_location: "example.log"
rocket: 
  mount_location: "/"
  port: "8000""#;
    let myYaml: Config = serde_yaml::from_str(yamlFile).unwrap();
}

Playground

If you really want to use Vec as part of your original schema, you would need some changes:

  • Probably ColorStruct should be an enum, but if not you just need to keep as the remaining examples.
  • Your yaml need to provide the data correcly too to match those types.

#[derive(Debug, Serialize, Deserialize)]
enum ColorStruct {
    fatal(String),
    error(String),
    warn(String),
    info(String),
    debug(String),
    trace(String),
}

...

let yamlFile = r#"default_verbosity: 0
logging: [
    {
        log_output: "file",
        file_location: "example.log",
        use_color: true,
        log_color: [
            { fatal: "Red" },
            { error: "Red" },
            { warn: "Red" },
            { info: "Green" },
            { debug: "Blue" },
            { trace: "Yellow" }
        ]
    }
]

rocket:  [
    {
        mount_location: "/",
        port: "8000"
    }
]"#;

...

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading