Introdução ao trabalho com YAML em Rust
YAML (YAML Ain't Markup Language) é um dos formatos mais populares para arquivos de configuração devido à sua legibilidade e flexibilidade. No ecossistema Rust, a crate serde_yaml é usada para trabalhar com YAML, construída sobre a poderosa plataforma de serialização Serde. Esta biblioteca permite converter facilmente estruturas Rust para YAML e vice-versa.
Instalação e configuração
Adicione as dependências ao seu Cargo.toml:
[dependencies]serde = { version = "1.0", features = ["derive"] }serde_yaml = "0.9"Após atualizar o projeto, execute cargo build. A biblioteca está pronta para uso.
Desserialização básica de YAML em Rust
Vamos considerar um exemplo simples — ler uma string YAML e convertê-la em uma estrutura Rust.
Passo 1: Definindo a estrutura
use serde::Deserialize;
#[derive(Debug, Deserialize)]struct Config { host: String, port: u16, debug: bool,}Passo 2: Parseando YAML
use serde_yaml;
fn main() -> Result<(), serde_yaml::Error> { let yaml_str = r#" host: "127.0.0.1" port: 8080 debug: true "#;
let config: Config = serde_yaml::from_str(yaml_str)?; println!("{:?}", config); Ok(())}Saída: Config { host: "127.0.0.1", port: 8080, debug: true }
Serialização de estruturas Rust para YAML
O processo inverso — converter dados Rust para uma string YAML:
use serde::Serialize;
#[derive(Debug, Serialize)]struct Server { name: String, ip: String, ports: Vec<u16>,}
fn main() -> Result<(), serde_yaml::Error> { let server = Server { name: "web-server".into(), ip: "10.0.0.1".into(), ports: vec![80, 443, 22], };
let yaml = serde_yaml::to_string(&server)?; println!("{}", yaml); Ok(())}Resultado:
---name: web-serverip: 10.0.0.1ports: - 80 - 443 - 22Trabalhando com estruturas aninhadas e tags
YAML suporta hierarquias complexas. Em Rust, isso é mapeado para estruturas e enumerações aninhadas:
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]struct Database { #[serde(rename = "db")] database: DbConfig, pool_size: u32,}
#[derive(Debug, Serialize, Deserialize)]struct DbConfig { host: String, port: u16, user: String, password: String,}
fn main() -> Result<(), serde_yaml::Error> { let yaml = r#" db: host: "localhost" port: 5432 user: "admin" password: "secret" pool_size: 10 "#;
let db: Database = serde_yaml::from_str(yaml)?; println!("{:#?}", db); Ok(())}Observe o atributo #[serde(rename = "db")] — ele permite mapear um campo Rust para um nome diferente em YAML.
Tratamento de erros e campos opcionais
Arquivos YAML reais frequentemente contêm parâmetros opcionais. Use Option<T>:
#[derive(Debug, Deserialize)]struct AppConfig { name: String, version: String, #[serde(default)] features: Vec<String>, #[serde(default = "default_timeout")] timeout: u64,}
fn default_timeout() -> u64 { 30}O atributo #[serde(default)] atribui um valor padrão (vetor vazio para Vec, None para Option). Você pode especificar uma função geradora, como no exemplo com timeout.
Lendo YAML de um arquivo
Na prática, as configurações são armazenadas em arquivos. A leitura é simples:
use std::fs;use serde_yaml;
fn main() -> Result<(), Box<dyn std::error::Error> Também na biblioteca
spdlog para C++: guia completo com exemplos
InversifyJS: Contêiner IoC para aplicações TypeScript
Frameworks CLI para Rust: visão geral das melhores ferramentas para criar utilitários de linha de comando
Aprendizado de Máquina em Swift: Core ML, Create ML, TensorFlow Swift e Turi Create
ORM para C++: comparação e exemplos de uso (ODB, SOCI, SQLiteCpp)