Rust 中 YAML 使用入门
YAML(YAML Ain't Markup Language)因其可读性和灵活性,是最流行的配置文件格式之一。在 Rust 生态系统中,用于处理 YAML 的 crate 是 serde_yaml,它构建在强大的 Serde 序列化框架之上。该库允许您轻松地在 Rust 结构体和 YAML 之间进行转换。
安装与配置
将依赖项添加到您的 Cargo.toml 中:
[dependencies]serde = { version = "1.0", features = ["derive"] }serde_yaml = "0.9"更新项目后,执行 cargo build。该库即可使用。
在 Rust 中基本反序列化 YAML
看一个最简单的例子——读取 YAML 字符串并将其转换为 Rust 结构体。
步骤 1:定义结构体
use serde::Deserialize;
#[derive(Debug, Deserialize)]struct Config { host: String, port: u16, debug: bool,}步骤 2:解析 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(())}输出:Config { host: "127.0.0.1", port: 8080, debug: true }
将 Rust 结构体序列化为 YAML
反向过程——将 Rust 数据转换为 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(())}结果:
---name: web-serverip: 10.0.0.1ports: - 80 - 443 - 22处理嵌套结构体和标签
YAML 支持复杂的层次结构。在 Rust 中,这映射为嵌套结构体和枚举:
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(())}请注意属性 #[serde(rename = "db")]——它允许将 Rust 字段与 YAML 中的不同名称进行匹配。
错误处理和可选字段
实际的 YAML 文件通常包含可选参数。请使用 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}属性 #[serde(default)] 会分配一个默认值(对于 Vec 是空向量,对于 Option 是 None)。您可以像 timeout 示例中那样指定一个生成器函数。
从文件读取 YAML
在实践中,配置存储在文件中。读取操作很简单:
use std::fs;use serde_yaml;
fn main() -> Result<(), Box<dyn std::error::Error>