Convertir JSON a estructuras Rust con Serde — Numio
Genera structs de Rust con los derives Serialize y Deserialize de serde a partir de una muestra JSON. Los campos pasan a snake_case con un atributo rename_all, las claves que faltan en algunos elementos de un array pasan a Option<T> y los valores null a serde_json::Value.
Tipar la respuesta de una API de terceros antes de deserializarla con serde_json en un cliente reqwest.
JSON
Rust Serde
Cuándo usarla
- Tipar la respuesta de una API de terceros antes de deserializarla con serde_json en un cliente reqwest.
- Escribir structs para un archivo de configuración o fixture JSON en una CLI de Rust o un servicio Axum.
Cómo usarla
- Pega la muestra JSON; si un campo es opcional, incluye elementos de array con y sin él.
- Abre la configuración y elige Property Name Format según cómo estén escritas las claves de tu JSON (por defecto camelCase). Define #[serde(rename_all = ...)]; las claves que no encajan reciben #[serde(rename = ...)].
- Copia el código y añade serde (con derive), serde_derive y serde_json a Cargo.toml, como esperan las líneas use generadas.
Entrada JSON
{
"orderId": "A-1001",
"total": 19.5,
"paid": true,
"coupon": null,
"items": [
{ "sku": "PEN-01", "qty": 2 },
{ "sku": "BOOK-7", "qty": 1, "giftWrap": true }
]
}Structs de 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>,
}Detalles y limitaciones
La generación se ejecuta en el navegador con el módulo WebAssembly json_typegen; no se envía nada a ningún servidor.
Los enteros pasan a i64 y los decimales a f64. null y los arrays vacíos dan serde_json::Value y Vec<Value>; sustitúyelos por tipos concretos como Option<String>.
Las palabras clave de Rust se renombran: una clave llamada type pasa a type_field con #[serde(rename = "type")].
Cada struct deriva Default, Debug, Clone y PartialEq además de Serialize y Deserialize; elimina los que no necesites.
FAQ
¿Qué cambia la opción Property Name Format?
Describe cómo están escritas las claves de tu JSON, no los nombres de los campos de Rust. Los campos son siempre snake_case; la opción elige el valor de rename_all para que serde los vuelva a mapear a camelCase, kebab-case, PascalCase, etc.
¿Cómo se detectan los campos opcionales?
Cuando los objetos de un mismo array tienen claves distintas, las claves que faltan en algunos elementos pasan a Option<T>. Un campo presente en todos los elementos de la muestra no es opcional, aunque tu API a veces lo omita.
¿La raíz del JSON puede ser un array?
Sí. Un array en la raíz produce pub type Root = Vec<Root2>; con un struct Root2 para los elementos.