TOML 是一种简单、符合人体工程学且可读的配置格式;Rust 的包管理器cargo
就使用 TOML 格式;本文介绍在 Rust 中如何来处理 TOML 格式的数据;
在 Rust中,可以使用toml
库来解析和生成 TOML 格式的数据;联合serde
和toml
,可以将 TOML 字符串解析为任意 Rust 结构体,或将 Rust 结构体序列化为 TOML 格式的字符串。
添加依赖
要使用toml
和serde
,需添加依赖,编辑Cargo.toml
文件,添加以下内容:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
toml = "0.9"
使用 toml 库
toml 库提供一个代表 TOML 表的结构体toml::Table
,可以使用它来访问和操作 TOML 格式的数据;
pub type Table = Map<String, Value>;
其中,Value
表示toml::Value
,是一个代表 TOML 值的枚举:
pub enum Value {
String(String),
Integer(i64),
Float(f64),
Boolean(bool),
Datetime(Datetime),
Array(Array),
Table(Table),
}
以下是一个简单的例子,演示了如何使用toml::Table
操作 TOML 表:
use toml::{Table, Value};
fn main() {
let mut table = Table::new();
// 插入键值对
table.insert("website".to_string(),Value::String("perfcode.com".to_string()));
table.insert("total".to_string(),Value::Integer(100));
table.insert("enabled".to_string(),Value::Boolean(true));
// 获取键值对
let website = table.get("website").unwrap().as_str().unwrap();
let total = table.get("total").unwrap().as_integer().unwrap();
let enabled = table.get("enabled").unwrap().as_bool().unwrap();
println!("website: {}, total: {}, enabled: {}", website, total, enabled);
// 遍历所有键值对
for (key, value) in table.iter() {
println!(" - {}: {:?}", key, value);
}
// 删除键值对
let removed_value = table.remove("total");
println!("removed value: {:?}", removed_value);
}
程序运行结果
website: perfcode.com, total: 100, enabled: true - enabled: Boolean(true) - total: Integer(100) - website: String("perfcode.com") removed value: Some(Integer(100))
解析TOML文档
解析 TOML 文档最简单的方法是通过Table
类型:
use toml::Table;
fn main(){
let toml_text = r#"
a = "perfcode.com"
b = true
[others]
c = 3
"#;
let value = toml_text.parse::<Table>().unwrap();
println!("{}\n{}\n{}",
value["a"].as_str().unwrap(),
value["b"].as_bool().unwrap(),
value["others"]["c"].as_integer().unwrap(),
);
}
程序运行结果
perfcode.com true 3
使用 toml::from_str 函数
toml 库提供一个toml::from_str
函数可将 TOML 文档解析(反序列化)成toml::Table
类型;修改前一个例子:
use toml::Table;
fn main(){
let toml_text = r#"
a = "perfcode.com"
b = true
[others]
c = 3
"#;
let value:Table = toml::from_str(&toml_text).unwrap();
println!("{}\n{}\n{}",
value["a"].as_str().unwrap(),
value["b"].as_bool().unwrap(),
value["others"]["c"].as_integer().unwrap(),
);
}
使用 toml::to_string 函数
可以使用toml::to_string
函数,将toml::Table
类型序列化成 TOML 字符串:
use toml::Table;
fn main(){
let toml_text = r#"
a = "perfcode.com"
"#;
let mut value:Table = toml::from_str(&toml_text).unwrap();
value.insert("b".to_string(),toml::Value::String("www.perfcode.com".to_string()));
let new_toml = toml::to_string(&value).unwrap();
println!("{}",new_toml);
}
程序运行结果
a = "perfcode.com" b = "www.perfcode.com"
对自定义结构体序列化和反序列化
一个 TOML 反序列化的例子:
use serde::{Deserialize,Serialize};
#[derive(Deserialize,Serialize)]
struct Config {
ip: String,
port: u16,
others: Others
}
#[derive(Deserialize,Serialize)]
struct Others {
salt: String,
use_whitelist: bool,
}
fn main(){
let tom_text = r#"
ip = "127.0.0.1"
port = 80
[others]
salt = "xxxxxx"
use_whitelist = false
"#;
let config:Config = toml::from_str(tom_text).unwrap();
println!("ip: {}\nport: {}\nsalt: {}\nuse_whitelist: {}",
config.ip,
config.port,
config.others.salt,
config.others.use_whitelist
);
}
程序运行结果
ip: 127.0.0.1 port: 80 salt: xxxxxx use_whitelist: false
一个 TOML 序列化的例子:
use serde::{Deserialize,Serialize};
#[derive(Deserialize,Serialize)]
struct Config {
ip: String,
port: u16,
others: Others
}
#[derive(Deserialize,Serialize)]
struct Others {
salt: String,
use_whitelist: bool,
}
fn main(){
// 序列化
let new_config = Config {
ip: "0.0.0.0".to_string(),
port: 80,
others: Others {
salt: "ssssssssss".to_string(),
use_whitelist: true
}
};
let new_toml = toml::to_string(&new_config).unwrap();
println!("{}",new_toml);
}
程序运行结果
ip = "0.0.0.0" port = 80 [others] salt = "ssssssssss" use_whitelist = true