toml-rsで、以下のPerson.toml
を読み込みます。
# Person.toml [profile] name = "Alice" age = 20
準備
toml-rsに加えて、
DeserializeにSerdeを使うので、Cargo.toml
に以下を追記します。
# Cargo.toml [dependencies] serde = "1.0" serde_derive = "1.0" toml = "0.4"
実装
パースは、toml::from_str()
でできるので、パースするための構造体を定義します。
今回は、読み込み元のtomlファイルに値が存在しないことを考慮して、Option
にしましたが、確実に値が存在するのであれば、Option
にしないのもありだと思います。(参照するときにunwrap()
だらけになりそうなので...)
#[derive(Debug, Deserialize)] struct Person { profile: Option<Profile>, } #[derive(Debug, Deserialize)] struct Profile { name: Option<String>, age: Option<i32>, }
ファイル読み込みからパースまでの実装です。
#[macro_use] extern crate serde_derive; extern crate toml; use std::fs; use std::io::{BufReader, Read}; #[derive(Debug, Deserialize)] struct Person { profile: Option<Profile>, } #[derive(Debug, Deserialize)] struct Profile { name: Option<String>, age: Option<i32>, } fn read_file(path: String) -> Result<String, String> { let mut file_content = String::new(); let mut fr = fs::File::open(path) .map(|f| BufReader::new(f)) .map_err(|e| e.to_string())?; fr.read_to_string(&mut file_content) .map_err(|e| e.to_string())?; Ok(file_content) } fn main() { let s = match read_file("./Person.toml".to_owned()) { Ok(s) => s, Err(e) => panic!("fail to read file: {}", e), }; let person: Result<Person, toml::de::Error> = toml::from_str(&s); match person { Ok(p) => println!("{:#?}", p), Err(e) => panic!("fail to parse toml: {}", e), }; }
実行
以下のようにパースできます。
❯ cargo run Person { profile: Some( Profile { name: Some( "Alice" ), age: Some( 20 ) } ) }