Trabalhando com CSV em Rust: biblioteca csv e exemplos práticos
O formato CSV (Comma-Separated Values) continua sendo uma das formas mais populares de armazenar dados tabulares. Em Rust, para trabalhar com CSV, existe a biblioteca madura e de alto desempenho csv, que fornece uma API conveniente para leitura, escrita e processamento de dados. Neste artigo, vamos detalhar como trabalhar eficientemente com CSV em Rust.
Instalação e inclusão da biblioteca
Para começar, adicione a dependência no arquivo Cargo.toml:
[dependencies]csv = "1.3"A biblioteca csv suporta trabalho com codificações, delimitadores e aspas configuráveis, além de fornecer a capacidade de serialização/desserialização de dados através dos traits serde.
Leitura de arquivo CSV
A maneira mais simples de ler um CSV é usar csv::Reader. Vejamos um exemplo com o arquivo users.csv:
use std::error::Error;use csv::ReaderBuilder;
fn main() -> Result<(), Box<dyn Error>> { // Criando um reader com configurações let mut rdr = ReaderBuilder::new() .has_headers(true) // primeira linha — cabeçalhos .delimiter(b',') // delimitador — vírgula .from_path("users.csv")?;
// Exibindo os cabeçalhos let headers = rdr.headers()?; println!("Headers: {:?}", headers);
// Iterando sobre os registros for result in rdr.records() { let record = result?; println!("{:?}", record); } Ok(())}Processamento de registros com desserialização
Para trabalhar com dados estruturados, é conveniente usar a desserialização em estruturas personalizadas. Adicione serde e serde_derive:
[dependencies]csv = "1.3"serde = { version = "1.0", features = ["derive"] }Agora você pode definir a estrutura e ler os dados diretamente:
use serde::Deserialize;
#[derive(Debug, Deserialize)]struct User { name: String, age: u8, email: String,}
fn main() -> Result<(), Box<dyn std::error::Error>> { let mut rdr = csv::Reader::from_path("users.csv")?;
for result in rdr.deserialize() { let user: User = result?; println!("Usuário: {} ({} anos) - {}", user.name, user.age, user.email); } Ok(())}Escrita de dados em CSV
Para escrita, usa-se csv::Writer. Exemplo de escrita de dados estruturados:
use csv::Writer;use serde::Serialize;
#[derive(Debug, Serialize)]struct Product { id: u32, name: String, price: f64, in_stock: bool,}
fn main() -> Result<(), Box<dyn std::error::Error>> { let mut wtr = Writer::from_path("products.csv")?;
// Escrevendo os cabeçalhos wtr.write_record(&["id", "name", "price", "in_stock"])?;
// Escrevendo dados via serialização let products = vec![ Product { id: 1, name: "Notebook".into(), price: 75000.50, in_stock: true }, Product { id: 2, name: "Mouse".into(), price: 1500.00, in_stock: false }, ];
for product in &products { wtr.serialize(product)?; }
wtr.flush()?; println!("Dados escritos em products.csv"); Ok(())}Configuração de delimitadores e aspas
A biblioteca permite configurar o formato de forma flexível. Por exemplo, para TSV (tabulação como delimitador):
let mut rdr = csv::ReaderBuilder::new() .delimiter(b'\\t') .flexible(true) // permitir número variável de campos .quoting(false) // desabilitar aspas .from_reader(io::stdin());Tratamento de erros e arquivos grandes
Ao trabalhar com arquivos CSV grandes, é importante considerar o desempenho. csv usa leitura bufferizada e não carrega
Também na biblioteca
Verificações de tipo condicional para TypeScript: guia completo com exemplos
Migrações de banco de dados em Kotlin: Visão geral de ferramentas e abordagens
Configuração de aplicativos Swift: ferramentas e bibliotecas para iOS/macOS