はじめに

ローカルのYAMLファイルを読み込んでいい感じにパースしてくれるライブラリはないかなと思って探したらyaml-rustがあったので試してみました。

やってみた

cargo new yaml-example
cd yaml-example

Cargo.tomlのdependenciesにyaml-rustを追記する

[dependencies]
yaml-rust = "0.4"

適当なyamlファイルをつくる

foo:
  - list1 
  - list2
bar:
  - 1
  - 2.0

yaml-rustのReadmeを参考にパース処理を書いてみる

extern crate yaml_rust;
use yaml_rust::{YamlLoader, YamlEmitter};
use std::fs;

fn load_yaml(path: &str) -> Vec<yaml_rust::Yaml> {
    let f = fs::read_to_string(path);
    let s = f.unwrap().to_string();
    let docs = YamlLoader::load_from_str(&s).unwrap();
    docs
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let path = "./sample.yaml";
    let docs = load_yaml(&path);
    let doc = &docs[0];
    // Test
    assert_eq!(doc["foo"][0].as_str().unwrap(), "list1");
    assert_eq!(doc["bar"][0].as_i64().unwrap(), 1);
    assert_eq!(doc["bar"][1].as_f64().unwrap(), 2.0);
    assert!(doc["INVALID_KEY"][100].is_badvalue());
    // Dump the YAML object
    let mut out_str = String::new();
    {
        let mut emitter = YamlEmitter::new(&mut out_str);
        emitter.dump(doc).unwrap();
    }
    println!("{}", out_str);
    Ok(())
}

実行してみる

cargo build
cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/yaml_rust`
---
foo:
  - list1
  - list2
bar:
  - 1
  - 2.0

できた。

おわりに

Yaml::Loaderはマルチドキュメントファイルをサポートしているのでドキュメントが1つのYamlの場合でも let doc = &docs[0]; のように配列で返ってきています。

パース後のデータは普通にHashMapになっているので便利。シンプルでよさげ。

bannerAds