はじめに
ハンズラボ Advent Calendar 2020 10日目を担当します@ryosukeeeeeです。
RustでJSONのserialize/deserializeするときはserdeとserde_jsonを使うのが一般的です。少なくとも私の観測範囲では。
ある日、モックサーバをRust書いていたのですがXMLをserializeする必要に迫られました。
serde-xml-rsというcrateが見つかったのですが、ハマったところがあったので記事にしました。
サンプル1
Using derive · SerdeのコードをXML版に置き換えたコードを載せます。
コード
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename = "root")]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_xml_rs::to_string(&point).unwrap();
println!("serialized = {}", serialized);
let deserialized: Point = serde_xml_rs::from_str("<root><x>3</x><y>4</y></root>").unwrap();
println!("deserialized = {:?}", deserialized);
}
実行結果
$ cargo run
serialized = <root><x>1</x><y>2</y></root>
deserialized = Point { x: 3, y: 4 }
ハマったところ
執筆時点での最新バージョン(0.4.0)ではVec型のserializeには対応していません。
試しに、サンプル2のようにVec型をもつ構造体Teamのserializeを実行してみました。
サンプル2
コード
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename = "team")]
struct Team {
people: Vec<Person>,
}
#[derive(Serialize)]
#[serde(rename = "person")]
struct Person {
name: String,
}
impl Person {
fn new(name: &str) -> Person {
Person {
name: name.to_string(),
}
}
}
fn main() {
let team = Team {
people: vec![Person::new("Joe"), Person::new("Jane")],
};
let serialized = serde_xml_rs::to_string(&team).unwrap();
println!("serialized = {}", serialized);
}
実行結果
$ cargo run
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: UnsupportedOperation { operation: "serialize_seq" }', src/main.rs:28:53
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
unwrap()
の処理でpanicしています。
serde-xml-rsのリポジトリをみてみると、Vec型へ対応したPRが複数提案されています。
ここではSupport seq and maps (refactor of #129) by adrianbenavides · Pull Request #142を使ってみましょう。
Cargo.tomlのdependenciesで↓のように指定します。
[dependencies]
serde-xml-rs = { git = "https://github.com/adrianbenavides/serde-xml-rs.git", rev = "fc2d35e5e2d08c4e8c8dee13449ff3ce98de46c1" }
なお、deserializeには対応していないようです。
実行結果
$ cargo run
serialized = <team><people><person><name>Joe</name></person><person><name>Jane</name></person></people></team>
めでたくserialize出来ました🚀
最後に
ハンズラボ Advent Calendar 2020 明日の11日目は、 @fasahina さんです!お楽しみに🎉