JSON a struct de Rust
Pega un objeto JSON o una respuesta de API y obtén structs de Rust idiomáticos que compilan con serde: campos en snake_case, #[serde(rename_all)] o renombrados por campo, Option<T> para valores que pueden ser nulos, Vec<T> para arrays y un struct para cada objeto anidado. Todo se ejecuta en tu navegador.
Última actualización:
Tu JSON se analiza localmente en esta pestaña y nunca se sube. Consejo: Ctrl + Intro genera el código.
Cómo usar JSON a struct de Rust
- Pega tu JSON en el cuadro de la izquierda o abre un archivo .json. Se carga un ejemplo para que veas la salida enseguida.
- Pon nombre al struct raíz, por ejemplo User o ApiResponse.
- Elige las opciones: qué derives de serde añadir, el tipo de entero, rename_all o renombrado por campo, Option para campos ausentes y derives adicionales.
- Pulsa Generar structs de Rust. Con Actualización en directo activada, el código se actualiza mientras escribes.
- Copia o descarga el archivo .rs, añade serde (con la feature derive) y serde_json a Cargo.toml, y llama a serde_json::from_str.
Ejemplo: de JSON a structs de Rust con serde
Esta respuesta tiene claves en camelCase, un valor que puede ser nulo, una palabra clave de Rust como clave y un array de objetos en el que una clave es opcional:
{ "userId": 42, "displayName": "Ada", "avatarUrl": null,
"posts": [ { "id": 1, "type": "article", "score": 4.5 },
{ "id": 2, "type": "note", "score": 3, "coverImage": "a.png" } ] }Con las opciones predeterminadas, el generador produce:
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
pub user_id: i64,
pub display_name: String,
pub avatar_url: Value,
pub posts: Vec<Post>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Post {
pub id: i64,
pub r#type: String,
pub score: f64,
pub cover_image: Option<String>,
}score es f64 porque un elemento tiene 4.5, cover_image es un Option porque solo una publicación lo tiene, y avatar_url es Value porque siempre es null, así que su tipo es desconocido. Cámbialo a Option<String> cuando lo sepas.
Cómo se corresponden los valores JSON con los tipos de Rust
| Valor JSON | Tipo de Rust |
|---|---|
"text" | String |
42 | i64 (o i32 / u64 según la opción) |
3.14, 1e6 | f64 |
true / false | bool |
"x" o null | Option<String> |
| Clave ausente en algunos elementos | Option<T> (o #[serde(default)]) |
{ … } | Un struct con nombre |
{} | HashMap<String, Value> |
[1, 2] / [] | Vec<i64> / Vec<Value> |
Solo null, o tipos mixtos | serde_json::Value |
Cómo usar los structs
# Cargo.toml
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
// main.rs
let root: Root = serde_json::from_str(&json)?;
println!("{}", root.posts[0].r#type);
let back = serde_json::to_string_pretty(&root)?;- Las claves desconocidas se ignoran por defecto. Activa
deny_unknown_fieldspara que la deserialización falle cuando el JSON tenga claves que el struct no conoce. - skip_serializing_if omite los campos
Noneen la salida en lugar de escribirnull, lo que mantiene el JSON serializado más cerca del original. - Las fechas se quedan como String. Para marcas de tiempo tipadas, añade el crate chrono con su feature serde y cambia el campo a
chrono::DateTime<chrono::Utc>.
Preguntas frecuentes
¿Qué crates necesitan los structs generados?
Añade serde con la feature derive y serde_json a Cargo.toml: serde = { version = "1", features = ["derive"] } y serde_json = "1". Los structs usan #[derive(Serialize, Deserialize)] de serde y, cuando un campo puede contener tipos mixtos, serde_json::Value.
¿Cómo se convierten las claves JSON en nombres de campo de Rust?
Cada clave se divide en palabras en los límites de camelCase, guiones, espacios y guiones bajos, y luego se une en snake_case, así que userName pasa a ser user_name. Si la mayoría de las claves de un struct siguen una convención, el generador añade #[serde(rename_all = "camelCase")] (o PascalCase, kebab-case o SCREAMING_SNAKE_CASE) y solo añade #[serde(rename = "...")] a las claves que no encajan, para que serde siga leyendo el JSON original.
¿Cuándo un campo pasa a ser Option<T>?
Un campo pasa a ser Option<T> cuando es null en al menos un sitio o (con la opción activada) cuando la clave falta en algunos elementos de un array. serde deserializa automáticamente un campo Option ausente como None. Si desactivas la opción, los campos ausentes reciben #[serde(default)] en su lugar.
¿Qué pasa con palabras clave de Rust como type o match?
Las palabras clave se escriben como identificadores raw, por ejemplo pub r#type: String. serde elimina el prefijo r#, así que el campo sigue correspondiendo a la clave JSON "type". self, Self, super y crate no pueden ser identificadores raw, así que reciben un guion bajo al final y un atributo rename.
¿Qué tipo reciben los números?
Los números enteros pasan a ser i64 por defecto, y los números con punto decimal o exponente pasan a ser f64. Puedes elegir i32 cuando todos los valores caben en 32 bits, o u64 cuando ningún valor es negativo. Si un campo mezcla enteros y decimales, pasa a ser f64. Los enteros demasiado grandes para 64 bits se tratan como f64.
¿Y los campos solo null, los arrays vacíos y los tipos mixtos?
Si un valor es siempre null, no se puede saber su tipo real, así que pasa a ser serde_json::Value. Los arrays vacíos pasan a ser Vec<Value>, y los campos que mezclan tipos (como una cadena en un elemento y un número en otro) también usan Value, porque Rust no tiene tipos unión ad hoc. Sustitúyelos por un tipo concreto o un enum cuando conozcas los datos.
¿Se sube mi JSON a algún sitio?
No. El análisis y la generación de código son JavaScript que se ejecuta en esta página, así que las respuestas de API con datos personales o secretos nunca salen de tu dispositivo.
¿Se prueban todas las herramientas de FreeToolCabin para comprobar su calidad y precisión?
Sí. Cada herramienta del sitio pasa pruebas automáticas en navegadores reales para comprobar que el resultado es correcto y que no hay errores. Si encuentras un fallo o tienes una sugerencia, escríbenos a [email protected] y lo revisaremos.
Herramientas relacionadas
Ver todas las de Conversores de datos y formatos de archivo →