Преобразование JSON в структуры Rust Serde — Numio
Генерирует структуры Rust с derive Serialize и Deserialize из serde по примеру JSON. Поля получают snake_case с атрибутом rename_all, ключи, отсутствующие в некоторых элементах массива, становятся Option<T>, а значения null — serde_json::Value.
Типизировать ответ стороннего API перед десериализацией через serde_json в клиенте reqwest.
JSON
Rust Serde
Когда пригодится
- Типизировать ответ стороннего API перед десериализацией через serde_json в клиенте reqwest.
- Написать структуры для JSON-конфига или фикстуры в Rust CLI или сервисе на Axum.
Как пользоваться
- Вставьте пример JSON; если поле необязательное, добавьте элементы массива как с ним, так и без него.
- Откройте настройки и выберите в Property Name Format стиль ключей в вашем JSON (по умолчанию camelCase). Он задаёт #[serde(rename_all = ...)]; ключи, которые ему не соответствуют, получают #[serde(rename = ...)].
- Скопируйте код и добавьте в Cargo.toml serde (с derive), serde_derive и serde_json, как того требуют сгенерированные строки use.
Ввод JSON
{
"orderId": "A-1001",
"total": 19.5,
"paid": true,
"coupon": null,
"items": [
{ "sku": "PEN-01", "qty": 2 },
{ "sku": "BOOK-7", "qty": 1, "giftWrap": true }
]
}Структуры Rust (serde)
use serde_derive::Deserialize;
use serde_derive::Serialize;
use serde_json::Value;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
pub order_id: String,
pub total: f64,
pub paid: bool,
pub coupon: Value,
pub items: Vec<Item>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Item {
pub sku: String,
pub qty: i64,
pub gift_wrap: Option<bool>,
}Подробности и ограничения
Генерация выполняется в браузере WebAssembly-модулем json_typegen; на сервер ничего не отправляется.
Целые числа становятся i64, дробные — f64. null и пустые массивы дают serde_json::Value и Vec<Value>; замените их конкретными типами, например Option<String>.
Ключевые слова Rust переименовываются: ключ type становится type_field с #[serde(rename = "type")].
Каждая структура, помимо Serialize и Deserialize, выводит Default, Debug, Clone и PartialEq; удалите ненужные.
FAQ
Что меняет настройка Property Name Format?
Она описывает, как записаны ключи в вашем JSON, а не имена полей Rust. Поля всегда в snake_case; настройка выбирает значение rename_all, чтобы serde сопоставлял их обратно с camelCase, kebab-case, PascalCase и т. д.
Как определяются необязательные поля?
Если у объектов в одном массиве разные ключи, ключи, отсутствующие в некоторых элементах, становятся Option<T>. Поле, присутствующее во всех элементах примера, не считается необязательным, даже если ваш API иногда его опускает.
Может ли корень JSON быть массивом?
Да. Корневой массив даёт pub type Root = Vec<Root2>; со struct Root2 для элементов.