Inicio › Herramientas para desarrolladores › JSON a struct de Rust

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.

Publicidad
Publicidad

Cómo usar JSON a struct de Rust

  1. Pega tu JSON en el cuadro de la izquierda o abre un archivo .json. Se carga un ejemplo para que veas la salida enseguida.
  2. Pon nombre al struct raíz, por ejemplo User o ApiResponse.
  3. 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.
  4. Pulsa Generar structs de Rust. Con Actualización en directo activada, el código se actualiza mientras escribes.
  5. 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 JSONTipo de Rust
"text"String
42i64 (o i32 / u64 según la opción)
3.14, 1e6f64
true / falsebool
"x" o nullOption<String>
Clave ausente en algunos elementosOption<T> (o #[serde(default)])
{ … }Un struct con nombre
{}HashMap<String, Value>
[1, 2] / []Vec<i64> / Vec<Value>
Solo null, o tipos mixtosserde_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_fields para que la deserialización falle cuando el JSON tenga claves que el struct no conoce.
  • skip_serializing_if omite los campos None en la salida en lugar de escribir null, 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 →