Rust から XML への変換ツール
Rust の struct または struct リテラルを貼り付けてください。きれいな XML が返ってきます。
このツールの役割
連携サービスの SOAP クライアント、システム設定ファイル、テストフィクスチャのために Rust の struct に対応する XML を手書きした経験があるなら、どれだけコピペが必要になるかご存じでしょう。ここに Rust を貼り付ければ、整形された XML を一発で返します。単一の struct、複数の struct と enum を含むファイル、値が入った let order = Order { ... }; リテラル — いずれも結果は同じ、すべてのフィールドが保持された完全な XML ドキュメントです。
単純な文字列置換ではありません。この変換ツールは Rust が serde 経由で実際にどうシリアライズするかを理解しています — serde-xml-rs や quick-xml が出力するのとほぼ同じ形です。f64 と f32 は素の数値テキストになり、String の値は XML エスケープされ、None を持つ Option<T> は空要素になります(#[serde(skip_serializing_if = "Option::is_none")] が付いていればスキップされます)。Vec<T> は一貫したコンテナ形状に従い、各 Vec はラッパー要素となり、要素型にちなんで名付けられた子要素を 1 項目につき 1 つ持ちます。
serde の属性は尊重されます。フィールドに付いた #[serde(rename = "x")] は出力の要素名を変更し、struct に付いた #[serde(rename = "x")] はラッピングする root を変更し、#[serde(skip)] はフィールドを落とし、#[serde(flatten)] はネストされた struct を 1 階層引き上げます。enum は serde 標準のタギングルールで出力されます — デフォルトは externally tagged、#[serde(tag = "...")] を設定すれば adjacently または internally tagged になります。より深く知りたい場合は、The Rust Book が下地となる所有権と型システムを理解するしっかりした出発点になります。
使い方
3 ステップ。5 行の struct を貼り付けても、モジュール全体を貼り付けても、動きは同じです。
Rust を貼り付ける(またはサンプルを試す)
左側のエディタに Rust をそのまま放り込んでください。struct、enum、値が入った struct リテラル、または 複数の型 を含むファイル — どれでも大丈夫です。まず現実的な例を見たければ サンプルを読み込む をクリックしてください。
use 文を削ったり、derive マクロを外したり、ライフタイム注釈を整えたりする必要はありません。rustfmt が残した形のまま置いてください。貼り付けるだけです。
変換をクリック
緑の 変換 ボタンをクリック。ツールが Rust を読み、すべての struct とフィールドを保持して、XML を一発で構築します。実行中は短いローディングインジケーターが表示されます。
XML をコピー
右側のパネルに、標準準拠の XML パーサーが受け付ける、インデント済みで整った XML が表示されます。SOAP リクエスト、設定ファイル、テストフィクスチャにそのままコピーしてください。
実際に役立つ場面
システムレベルの SOAP 連携
Rust のサービスは、今も SOAP を話すレガシーシステムの隣に置かれることがよくあります。リクエスト struct を貼り付け、XML ボディを取り出し、HTTP クライアントを配線する前に SoapUI で検証 — envelope を手書きするより速いです。トランスポートには <a href="https://crates.io/" target="_blank" rel="noopener">crates.io</a> の <code>reqwest</code> のようなクレートを組み合わせてください。
サービスやデーモンの設定ファイル
30 以上のフィールドを持つ設定 struct が、編集しやすい XML テンプレートになります。手書きのボイラープレート不要、struct が増えてもフィールド漏れなし。
テストフィクスチャの種データ
ユニットテストで値が入った <code>let order = Order { ... };</code> を、統合テスト、モックサーバー、自分が持っていないレガシーシステム向けの XML シードファイルに変換します。
ドキュメントを同期させ続ける
README、クレートドキュメント、XSD ベースのスキーマドキュメント用の XML サンプルを、実際の struct から直接生成。ドキュメントがコードから乖離せず、一致し続けます。
よくある質問
複数の struct を一度に貼り付けられますか?
はい — モジュール全体を貼り付けてください。トップレベルの struct や enum はそれぞれ、ネストした型が展開され、デフォルト値が埋められた形で出力されます。何かが黙って捨てられることはありません。
#[serde(rename)] と #[serde(skip)] は尊重されますか?
はい。フィールドの #[serde(rename = "x")] は XML 要素名を変え、struct の #[serde(rename = "x")] はラッピング root を変え、#[serde(skip)] はフィールドを完全に落とし、#[serde(flatten)] はネストされた struct を 1 階層引き上げます。#[serde(rename_all = "PascalCase")] は struct 内の全フィールドに適用されます。これは serde がランタイムで実際にやることと一致します。
Option<T> と skip_serializing_if はどう扱われますか?
デフォルトでは None は空要素になります — 形状が一貫して保たれ、XSD のバリデーションも通り続けます。フィールドに #[serde(skip_serializing_if = "Option::is_none")] が付いていれば、None は丸ごと落とされます。Some(x) は常に x 自身としてシリアライズされます。
enum、Vec、HashMap はどうなりますか?
enum はデフォルトで externally-tagged(<VariantName>...</VariantName>)。#[serde(tag = "type")] を付ければ internally-tagged に切り替わります。Vec<T> はコンテナ要素になり、要素型にちなんだ名前の子を 1 項目につき 1 つ持ちます — Vec<OrderItem> items は <items><OrderItem/><OrderItem/></items> になります。HashMap<K,V> は <Entry><Key/><Value/></Entry> のコンテナになります。
コードは保存されますか?
コードは変換のためにバックエンドに送信されますが、保存はされません — ペイロードのログも取っていません。オンラインツール全般に言えることですが、本当に機密性の高いコードなら貼り付ける前に目を通してください。
Rust にライフタイム、trait、unsafe ブロックがある場合は?
ライフタイム注釈は XML 的には削られます — ランタイムの値には影響しません。trait 定義は形を表すもので内容は表さないので、直接 XML を生み出すことはありません — 実装している struct が生み出します。unsafe ブロックは実行時の構文なので無視されます。コードに構文エラーがあれば、まず明らかなものを直してください — パーサーは寛容ですが、読心能力はありません。
他にも便利なツール
Rust から XML はパズルの一片です。次のツールと相性がいいです: