cargo init read-conf
cd read-conf
read-conf git:(master) ✗ ls
Cargo.lock Cargo.toml config.json config.toml config.yaml src target
读取并解析json文件
config.json:
{
"mysql": {
"host": "localhost",
"port": 3306,
"username": "your_mysql_username",
"password": "your_mysql_password",
"database": "your_database_name",
"charset": "utf8mb4",
"collation": "utf8mb4_unicode_ci"
},
"redis": {
"host": "localhost",
"port": 6379,
"password": "your_redis_password",
"db": 0,
"prefix": "myapp:",
"options": {
"abort_on_connect_fail": false,
"read_timeout": 0,
"retry_interval": 15,
"retry_limit": 0
}
}
}
Cargo.toml:
[package]
name = "read-conf"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
main.rs:
use std::fs;
use std::io::Read;
use serde::Deserialize; // 修改了这里
#[derive(Deserialize, Debug)]
struct Config {
mysql: MySqlConfig,
redis: RedisConfig,
}
#[derive(Deserialize, Debug)]
struct MySqlConfig {
host: String,
port: u16,
username: String,
password: String,
database: String,
charset: String,
collation: String,
}
#[derive(Deserialize, Debug)]
struct RedisConfig {
host: String,
port: u16,
password: Option<String>,
db: u8,
prefix: String,
options: RedisOptions,
}
#[derive(Deserialize, Debug)]
struct RedisOptions {
abort_on_connect_fail: bool,
read_timeout: u64,
retry_interval: u64,
retry_limit: u64,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut file = fs::File::open("config.json")?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let config: Config = serde_json::from_str(&contents)?;
println!("MySQL Config:");
println!(" Host: {}", config.mysql.host);
println!(" Port: {}", config.mysql.port);
println!(" Username: {}", config.mysql.username);
println!(" Password: {}", config.mysql.password);
println!(" Database: {}", config.mysql.database);
println!(" Charset: {}", config.mysql.charset);
println!(" Collation: {}", config.mysql.collation);
println!("MySQL Config:");
println!(" Host: {}", config.redis.host);
println!(" Port: {}", config.redis.port);
// println!(" Password: {}", config.redis.password);// `std::option::Option<std::string::String>` cannot be formatted with the default formatter
// 使用unwrap_or_else来处理Option<String>
if let Some(password) = config.redis.password {
println!(" Password: {}", password);
} else {
println!(" Password: <not set>");
}
println!(" Db: {}", config.redis.db);
println!(" Prefix: {}", config.redis.prefix);
println!(" abort_on_connect_fail: {}", config.redis.options.abort_on_connect_fail);
println!(" read_timeout: {}", config.redis.options.read_timeout);
println!(" retry_interval: {}", config.redis.options.retry_interval);
println!(" retry_limit: {}", config.redis.options.retry_limit);
Ok(())
}
输出:
MySQL Config:
Host: localhost
Port: 3306
Username: your_mysql_username
Password: your_mysql_password
Database: your_database_name
Charset: utf8mb4
Collation: utf8mb4_unicode_ci
MySQL Config:
Host: localhost
Port: 6379
Password: your_redis_password
Db: 0
Prefix: myapp:
abort_on_connect_fail: false
read_timeout: 0
retry_interval: 15
retry_limit: 0
读取并解析yaml文件
config.yaml:
users:
- user: Alice
age: 28
hometown: New York
- user: Bob
age: 35
hometown: San Francisco
- user: Charlie
age: 22
hometown: Chicago
Cargo.toml:
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
main.rs:
use serde::Deserialize;
use std::fs::File;
use std::io::Read;
#[derive(Deserialize, Debug)]
struct User {
user: String,
age: u32,
hometown: String,
}
#[derive(Deserialize, Debug)]
struct UsersConfig {
users: Vec<User>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 打开YAML文件
let mut file = File::open("config.yaml")?;
// 读取文件内容
let mut content = String::new();
file.read_to_string(&mut content)?;
// 将字符串解析为Rust结构体
let config: UsersConfig = serde_yaml::from_str(&content)?;
// 打印解析后的结果
println!("{:#?}", config);
// 访问第一个用户的hometown
if let Some(first_user) = config.users.first() {
println!("第一个用户的家乡是: {}", first_user.hometown);
} else {
println!("YAML文件中没有用户");
}
// 访问第二个用户的user名
if let Some(second_user) = config.users.get(1) { // 索引1 即第二个元素
println!("第二个用户的名称是: {}", second_user.user);
} else {
println!("YAML文件中没有第二个用户");
}
Ok(())
}
输出:
UsersConfig {
users: [
User {
user: "Alice",
age: 28,
hometown: "New York",
},
User {
user: "Bob",
age: 35,
hometown: "San Francisco",
},
User {
user: "Charlie",
age: 22,
hometown: "Chicago",
},
],
}
第一个用户的家乡是: New York
第二个用户的名称是: Bob
读取并解析toml文件
config.toml:
# config.toml
# 中国四大名著的作者、籍贯、年代等信息
# 书籍信息
[[books]]
title = "三国演义"
author = "罗贯中"
origin = "山西太原(或浙江杭州)"
dynasty = "元末明初"
years = "约1330年-约1400年"
[[books]]
title = "水浒传"
author = "施耐庵"
origin = "江苏兴化"
dynasty = "元末明初"
years = "1296年-1370年"
[[books]]
title = "西游记"
author = "吴承恩"
origin = "江苏淮安"
dynasty = "明朝"
years = "1501年-1582年"
[[books]]
title = "红楼梦"
author = "曹雪芹"
origin = "辽宁辽阳"
dynasty = "清朝"
years = "约1715年-约1763年"
# 主要人物及简介
[[main_characters]]
book = "三国演义"
name = "诸葛亮"
description = "字孔明,号卧龙,蜀汉丞相,智谋过人,运筹帷幄之中,决胜千里之外。"
[[main_characters]]
book = "三国演义"
name = "曹操"
description = "字孟德,一代枭雄,多疑而爱惜人才,奠定了曹魏政权的基础。"
[[main_characters]]
book = "水浒传"
name = "宋江"
description = "字公明,梁山泊好汉的首领,讲义气,仗义疏财,领导梁山好汉反抗朝廷。"
[[main_characters]]
book = "水浒传"
name = "武松"
description = "行者武松,嫉恶如仇,行侠仗义,敢作敢为,曾打虎景阳冈,血溅鸳鸯楼。"
[[main_characters]]
book = "西游记"
name = "孙悟空"
description = "又名美猴王,不畏自然艰险,具有锄强扶弱、抱打不平的英雄本色,嫉恶如仇。"
[[main_characters]]
book = "西游记"
name = "唐僧"
description = "取经人,法名玄奘,又称三藏,宅心仁厚,有点不辨善恶,是孙悟空等人的师父。"
[[main_characters]]
book = "红楼梦"
name = "贾宝玉"
description = "贾家公子,对封建正统思想不满,追求自由,与林黛玉、薛宝钗等人物有深厚的情感纠葛。"
[[main_characters]]
book = "红楼梦"
name = "林黛玉"
description = "贾家表亲,聪明伶俐,多愁善感,与贾宝玉有深厚的感情,是书中重要的女性角色。"
Cargo.toml:
[dependencies]
toml = "0.5"
把书籍名称作为key,书中主要人物作为value,组成一个hash,并打印出来
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use toml::Value;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 打开TOML文件
let mut file = File::open("config.toml")?;
// 读取文件内容
let mut content = String::new();
file.read_to_string(&mut content)?;
// 解析TOML字符串为Value
let toml_value: Value = toml::from_str(&content)?;
// 创建一个空的HashMap来存储书籍和其主要人物
let mut books_characters: HashMap<String, Vec<String>> = HashMap::new();
// 假设每个书籍的主要人物都存储在main_characters数组中
if let Some(books) = toml_value.get("books").and_then(|a| a.as_array()) {
for book in books {
if let Some(title) = book.get("title").and_then(|t| t.as_str()) {
let mut characters = Vec::new();
// 获取与当前书籍相关的主要人物
if let Some(main_characters) = toml_value.get("main_characters").and_then(|a| a.as_array()) {
for character in main_characters {
if let Some(book_name) = character.get("book").and_then(|b| b.as_str()) {
if book_name == title {
if let Some(name) = character.get("name").and_then(|n| n.as_str()) {
characters.push(name.to_string());
}
}
}
}
}
// 将书籍名称和主要人物列表添加到HashMap中
books_characters.insert(title.to_string(), characters);
}
}
}
// 打印HashMap的内容
for (title, characters) in &books_characters {
println!("{} 的主要人物有: {:?}", title, characters);
}
Ok(())
}
输出:
三国演义 的主要人物有: ["诸葛亮", "曹操"]
西游记 的主要人物有: ["孙悟空", "唐僧"]
红楼梦 的主要人物有: ["贾宝玉", "林黛玉"]
水浒传 的主要人物有: ["宋江", "武松"]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。