Por que Rust é o candidato ideal para automação
Quando se trata de automatizar tarefas rotineiras, a maioria dos desenvolvedores logo pensa em Python ou Bash. E isso é lógico: eles são simples, flexíveis e possuem uma enorme quantidade de bibliotecas prontas. Mas o que fazer se o script começar a ficar lento com grandes volumes de dados? Ou se for necessário garantir que o programa não falhe com um erro crítico no momento mais inoportuno?
É aqui que entra o Rust. Uma linguagem que combina a performance do C/C++ com a segurança de memória de linguagens gerenciadas. Para tarefas de automação, isso oferece três vantagens principais:
- Velocidade — Rust compila para código nativo, proporcionando um ganho de 10 a 100 vezes em comparação com linguagens interpretadas.
- Confiabilidade — o compilador detecta a maioria dos erros antes da execução (condições de corrida, ponteiros soltos, tratamento de erros esquecido).
- Economia de recursos — consumo mínimo de memória e processador permite executar utilitários em Raspberry Pi ou servidores antigos.
Neste artigo, vamos analisar três cenários reais de automação com Rust: renomeação em lote de arquivos, monitoramento de recursos web e parsing de logs. Você verá como escrever código conciso, porém confiável, e entenderá quando Rust realmente justifica o investimento em seu aprendizado.
Cenário 1: Renomeação em lote de arquivos com verificação e logs
Imagine: você tem uma pasta com centenas de fotos no formato IMG_20231201_143022.jpg. Precisa renomeá-las para o formato 2023-12-01_photo_001.jpg. Em Bash, isso pode ser feito em algumas linhas, mas e se os nomes contiverem caracteres não padrão, duplicatas ou for necessário manter um log detalhado?
Rust, com seu sistema de tipos rigoroso e a crate std::fs, lida com isso de forma elegante e segura.
Implementação em Rust
use std::fs;use std::path::Path;use std::io;use chrono::NaiveDateTime;
fn main() -> io::Result<()> { let dir = Path::new("./photos"); let mut counter = 1u32;
for entry in fs::read_dir(dir)? { let entry = entry?; let path = entry.path(); if path.extension().map_or(false, |ext| ext == "jpg") { let stem = path.file_stem().unwrap().to_str().unwrap(); // Parse a data do nome: IMG_20231201_143022 -> 2023-12-01 14:30:22 if let Some(date_part) = stem.split('_').nth(1) { if let Ok(dt) = NaiveDateTime::parse_from_str( &format!("{} {}", &date_part[0..8], &date_part[8..14] ), "%Y%m%d %H%M%S" ) { let new_name = format!( "{}_photo_{:03}.jpg", dt.format("%Y-%m-%d"), counter ); let new_path = dir.join(&new_name); fs::rename(&path, &new_path)?; println!("✅ {} -> {}", path.display(), new_name); counter += 1; } else { eprintln!("⚠️ Não foi possível analisar a data: {}", path.display()); } } } } println!("🎉 Processados {} arquivos", counter - 1); Ok(())}Observe o tratamento de erros: io::Result e eprintln para arquivos problemáticos. O compilador Rust forçará você a tratar explicitamente cada possível falha — seja falta de permissão de leitura ou formato de data inválido. Isso significa que seu script de automação não "silenciará" no primeiro erro, mas informará claramente o que deu errado.
Benchmark: Para 10.000 arquivos, a versão em Rust é executada em 0,8 segundos, enquanto um script semelhante em Pyth