The serde_yaml library: working with YAML in Rust
YAML (YAML Ain't Markup Language) is one of the most popular data serialization formats, widely used for configuration files, describing data structures, and exchanging information between services. In the Rust ecosystem, there is a mature and performant library serde_yaml for working with YAML, built on top of the powerful serialization framework serde. In this article, we will take a detailed look at how to parse, create, and process YAML documents in Rust.
Installation and setup
To get started, add the following dependencies to your Cargo.toml:
[dependencies]serde = { version = "1.0", features = ["derive"] }serde_yaml = "0.9"The serde_yaml library will automatically pull in all necessary components for parsing and generating YAML.
Basic deserialization (YAML → Rust struct)
The most common scenario is reading a configuration file. Let's define a struct that corresponds to the YAML document:
use serde::Deserialize;
#[derive(Debug, Deserialize)]struct Config { server: ServerConfig, database: DatabaseConfig,}
#[derive(Debug, Deserialize)]struct ServerConfig { host: String, port: u16, workers: Option<u32>,}
#[derive(Debug, Deserialize)]struct DatabaseConfig { url: String, pool_size: u32,}Now let's read the YAML file and convert it into the struct:
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> { let yaml_content = fs::read_to_string("config.yaml")?; let config: Config = serde_yaml::from_str(&yaml_content)?; println!("Server: {}:{}", config.server.host, config.server.port); println!("Database: {}", config.database.url); Ok(())}Example of the config.yaml file:
server: host: "127.0.0.1" port: 8080 workers: 4database: url: "postgres://user:pass@localhost/db" pool_size: 10Serialization (Rust struct → YAML)
The reverse process — creating a YAML document from data in memory:
use serde::Serialize;
#[derive(Debug, Serialize)]struct Project { name: String, version: String, dependencies: Vec<Dependency>,}
#[derive(Debug, Serialize)]struct Dependency { name: String, version: String, optional: bool,}
fn main() -> Result<(), Box<dyn std::error::Error>> { let project = Project { name: "my-app".to_string(), version: "0.1.0".to_string(), dependencies: vec![ Dependency { name: "serde".to_string(), version: "1.0".to_string(), optional: false, }, Dependency { name: "tokio".to_string(), version: "1.35".to_string(), optional: true, }, ], };
let yaml_string = serde_yaml::to_string(&project)?; println!("{}", yaml_string); // Save to file std::fs::write("project.yaml", &yaml_string)?; Ok(())}Working with arbitrary YAML documents
Sometimes the structure of YAML is not known in advance. In such cases, use serde_yaml::Value:
use serde_yaml::Value;
fn main() -> Result<(), Box<dyn std::error::Error>> { let yaml_data = "apiVersion: v1kind: Servicemetadata: name: my-service labels: app: webspec: ports: - port: 80 targetPort: 8080 selector: app: web"; let value: Value = serde_yaml::from_str(yaml_data)?; // Access nested data if let Some(ports) = value["spec"]["ports"].as_sequence() { for port in ports { if let Some(port_num Also in library
Machine Learning in JavaScript: Libraries for Node.js — Overview and Examples
Swift WebSocket Libraries: Starscream and URLSessionWebSocketTask
Cryptography in Java: Encryption and Hashing – A Practical Guide
Symfony for PHP: Complete Guide with Examples