はじめに
ローカルのYAMLファイルを読み込んでいい感じにパースしてくれるライブラリはないかなと思って探したらyaml-rustがあったので試してみました。
やってみた
cargo new yaml-example
cd yaml-example
Cargo.toml
のdependencies
にyaml-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になっているので便利。シンプルでよさげ。