LoginSignup
5
2

More than 3 years have passed since last update.

RustでYAMLをパースする

Posted at

はじめに

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

やってみた

cargo new yaml-example
cd yaml-example

Cargo.tomldependenciesyaml-rustを追記する

Cargo.toml
[dependencies]
yaml-rust = "0.4"

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

sample.yaml
foo:
  - list1 
  - list2
bar:
  - 1
  - 2.0

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

src/main.rs
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になっているので便利。シンプルでよさげ。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2