Working with YAML in Rust: the serde_yaml library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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: 10


Serialization (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

Recommendations