Cómo serializo este struct con serde en Rust

Publicado por Brisa
hace 2 meses

Hola a todos,

Estoy intentando realizar la serialización de una struct en Rust utilizando la librería serde, pero estoy teniendo algunos problemas.

Aquí está el código de mi struct:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Persona {
    nombre: String,
    edad: u32,
}

Y aquí está el código donde intento serializar la struct y guardarlo en un archivo:

use std::error::Error;
use std::fs::File;
use std::io::Write;
use serde_json::to_writer;

fn main() -> Result<(), Box<dyn Error>> {
    let persona = Persona {
        nombre: String::from("Juan"),
        edad: 25,
    };

    let file = File::create("persona.json")?;
    let writer = to_writer(file, &persona)?;
    writer.flush()?;

    Ok(())
}

Cuando intento compilar el código, obtengo el siguiente error:

error[E0412]: cannot find type `Persona` in this scope
 --> src/main.rs:9:11
  |
9 |     let persona = Persona {
  |               ^^^^^^^ not found in this scope
...
15 | fn main() -> Result<(), Box<dyn Error>> {
  |                       ----------------- required by `main`

Intenté importar el módulo donde se encuentra la struct, pero sigo obteniendo el mismo error.

¿Alguien puede indicarme qué estoy haciendo mal?

Muchas gracias.

rust
Respuesta de Gordon Shumway
hace 2 meses

¡Hola Brisa!

El error que estás teniendo indica que Rust no puede encontrar la definición de Persona dentro del alcance de tu función main. Este error comúnmente ocurre si la definición de la struct está en un módulo diferente y no se ha importado correctamente, o simplemente si la definición de la struct no está en el mismo archivo y te has olvidado de declararla. Aquí, basándonos en el fragmento de código proporcionado, parece que la definición de la struct y la función main están en el mismo archivo. Por lo tanto, asegúrate de que la definición de Persona esté en el espacio de nombres global y anterior a la función main.

Otra cosa que noté es que en la línea donde utilizas to_writer, parece que estás esperando que esta función te devuelva un writer, pero en realidad to_writer no devuelve nada (en términos de Rust, devuelve ()), directamente escribe en el objeto Write proporcionado. Por lo tanto, no necesitas asignar la llamada a to_writer a ninguna variable, simplemente llámala. Además, no es necesario llamar a flush ya que to_writer debería encargarse de eso.

El código corregido sería algo como esto:

use serde_json::to_writer;
use serde::{Serialize, Deserialize};
use std::error::Error;
use std::fs::File;

// Asegúrate de que `Persona` esté definida antes y en el mismo scope que `main`.
#[derive(Serialize, Deserialize, Debug)]
struct Persona {
    nombre: String,
    edad: u32,
}

fn main() -> Result<(), Box<dyn Error>> {
    let persona = Persona {
        nombre: String::from("Juan"),
        edad: 25,
    };

    let file = File::create("persona.json")?;

    // No hay necesidad de asignar la salida de `to_writer`, tampoco usar `flush`.
    to_writer(file, &persona)?;

    Ok(())
}

Ahora tu código debería compilar y funcionar como esperas. Al ejecutar la función main, se creará un archivo llamado persona.json con la serialización JSON de tu struct Persona.

Espero que esto ayude. ¡Suerte con tu proyecto en Rust!