解析 Yaml 文件

Parsing Yaml file

最近 3 天,我试图找出如何在 Rust 中解析我的 yaml。 而且我不明白为什么它不起作用。

我的 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

但我的程序在解包行失败:let myYaml: Config = serde_yaml::from_reader(yamlFile).unwrap(); 并显示此错误消息:

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

我的程序:

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

对此我真的很沮丧。我究竟做错了什么?我的结构中是否遗漏了什么?

您的架构和 yaml 都错了。主要原因:

  • 你应该有嵌套结构,而不是 Vec
  • 您的 yaml 类型不准确,例如 True 是字符串,true 是布尔。 8000 不是 String"8000" 是。
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

如果您真的想将 Vec 用作原始架构的一部分,则需要进行一些更改:

  • 可能 ColorStruct 应该是枚举,但如果不是,您只需要保留其余示例即可。
  • 您的 yaml 也需要正确提供数据以匹配这些类型。

#[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