Trabajo con CSV en Rust: bibliotecas csv, serde y procesamiento eficiente de datos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo con CSV en Rust: bibliotecas, ejemplos de código y mejores prácticas



CSV (Comma-Separated Values) es uno de los formatos más comunes para almacenar datos tabulares. En el ecosistema de Rust existe una biblioteca potente y flexible llamada csv, que combinada con el crate serde permite leer, escribir y transformar datos CSV de manera cómoda. En este artículo analizaremos en detalle cómo trabajar con CSV en Rust, comenzando con el análisis básico hasta la serialización de estructuras complejas.



Instalación y configuración de dependencias



Para empezar, agregue las siguientes dependencias al archivo Cargo.toml:



[dependencies]csv = "1.3"serde = { version = "1.0", features = ["derive"] }


La biblioteca csv proporciona una API de bajo nivel para lectura y escritura, mientras que serde ofrece deserialización automática de filas CSV en estructuras de Rust.



Lectura de un archivo CSV línea por línea



La forma más sencilla de leer un CSV es usando Reader del crate csv. Veamos un ejemplo con el archivo users.csv:



use csv::Reader;use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> { let mut rdr = Reader::from_path("users.csv")?;

for result in rdr.records() { let record = result?; println!("{:?}", record); } Ok(())}


Este código imprime cada fila como un vector de cadenas StringRecord. Sin embargo, en la práctica es más común trabajar con datos tipados.



Deserialización en estructuras con serde



Declaremos una estructura que corresponda a las columnas del CSV:



use serde::Deserialize;

#[derive(Debug, Deserialize)]struct User { name: String, age: u32, city: String,}


Ahora podemos leer los registros directamente en instancias de User:



use csv::Reader;use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> { let mut rdr = Reader::from_path("users.csv")?;

for result in rdr.deserialize() { let user: User = result?; println!("{} ({} años) de {}", user.name, user.age, user.city); } Ok(())}


La biblioteca asigna automáticamente los encabezados del CSV a los campos de la estructura. Si el orden o los nombres de las columnas difieren, use el atributo #[serde(rename = "...")].



Escritura de un archivo CSV



La creación de un archivo CSV se realiza con Writer. Escritura de datos estructurados mediante serde:



use csv::Writer;use serde::Serialize;use std::error::Error;

#[derive(Debug, Serialize)]struct Product { id: u32, name: String, price: f64,}

fn main() -> Result<(), Box<dyn Error>> { let mut wtr = Writer::from_path("products.csv")?;

let products = vec![ Product { id: 1, name: "Portátil".into(), price: 75000.0 }, Product { id: 2, name: "Ratón".into(), price: 1500.0 }, ];

for product in &products { wtr.serialize(product)?; }

wtr.flush()?; println!("Archivo products.csv escrito exitosamente"); Ok(())}


Tenga en cuenta: Writer agrega automáticamente los encabezados basándose en los nombres de los campos de la estructura.



Configuración de delimitadores y comillas



Por defecto se utilizan comas y comillas dobles. Si su archivo usa punto y coma (por ejemplo, en configuraciones regionales europeas), configure ReaderBuilder:



use csv::ReaderBuilder;

let mut rdr = ReaderBuilder::new() .delimiter(b';') .has_headers(true) .from_path("data.tsv")?;


De manera similar se configura WriterBuilder para la escritura.



Manejo de errores y datos no válidos



Recommendations