|
跟着hunter老师学习了几天Rust,今天小试一下,来完成任务2 ,用fs的API trait来读写一下 Cargo.toml文件
我先写的code是这样的:
在terminal 中 cargo run 一下,如下
看一下,仅仅println!() 就少了好几个“!”,小菜鸟起步的必经之路,呜呜。。。
Rust编译非常好用和友善,错误都有提示,根据错误提示一步一步改bug,
得到了下面的code
这一步有遇到了一个问题,就是所有权问题,使用clone 就可以了,看看提示
修改这个问题后,接下来应该ok了吧,no no no...
追查了一下发现,错误发生在尝试将 Rust 数据结构序列化回 TOML 格式时,原因是 TOML 格式要求所有的值(values)必须在表(tables)之前出现。继续修改,最终code如下:
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
/*
// define a struct to represent Cargo.tom file
#[derive(Debug, Serialize, Deserialize)]
struct CargoTom {
package: Package,
dependencies: Option<toml::value::Table>,
#[serde(rename = "dev-dependencies")]
dev_dependencies: Option<toml::value::Table>,
#[serde(rename = "build-dependencies")]
build_dependencies: Option<toml::value::Table>,
}
*/
// define a struct to represent Cargo.toml file
#[derive(Debug, Serialize, Deserialize)]
struct CargoTom {
package: Package,
dependencies: Option<toml::value::Table>,
#[serde(flatten)]
other: toml::value::Table,
}
#[derive(Debug, Serialize, Deserialize)]
struct Package {
name: String,
version: String,
authors: Option<Vec<String>>,
edition: Option<String>,
}
fn main() -> Result<()> {
let cargo_toml_path = Path::new("./Cargo.toml") ;
// read the Cargo.toml file
let content = fs::read_to_string(cargo_toml_path).context("Failed to read Cargo.toml")?;
// parse the Cargo.toml file
let mut cargo_toml: CargoTom = toml::from_str(&content).context("Failed to parse Cargo.toml")?;
// print the parsed Cargo.toml file
println!(" == original Cargo.toml file ==");
println!("{:#?}", cargo_toml);
// modify the parsed Cargo.toml file
cargo_toml.package.version = "0.2.0".to_string();
// add a new dependency to the parsed Cargo.toml file
if let Some(deps) = cargo_toml.other.get_mut("dependencies") {
if let Some(table) = deps.as_table_mut() {
table.insert("new_dep".to_string(), toml::value::Value::String("1.0.36".to_string()));
}
} else {
let mut deps = toml::value::Table::new();
deps.insert("new_dep".to_string(), toml::value::Value::String("1.0.36".to_string()));
cargo_toml.other.insert("dependencies".to_string(), toml::value::Value::Table(deps));
}
// serialize the modified Cargo.toml file to string
let mut update_content = String::new();
// firstly, serialize the package section
let package_toml = toml::to_string(&cargo_toml.package).context("Failed to serialize package section")?;
update_content.push_str(&package_toml);
// then, serialize the dependencies section
if let Some(deps) = cargo_toml.other.get("dependencies") {
let deps_toml = toml::to_string(deps).context("Failed to serialize dependencies section")?;
update_content.push_str("\n");
update_content.push_str(&deps_toml);
}
// finally, serialize the rest sections
/*for (key, value) in cargo_toml.other.iter() {
if key != "dependencies" {
let section_toml = toml::to_string(value).context(format!("Failed to serialize section {}", key))?;
update_content.push_str("\n");
update_content.push_str(§ion_toml);
}
}*/
// 然后序列化其他部分
for (key, value) in cargo_toml.other {
update_content.push_str(&format!("\n[{}]\n", key));
let section_toml = toml::to_string(&value)
.context(format!("Failed to serialize {}", key))?;
update_content.push_str(§ion_toml);
}
// print the modified Cargo.toml file
println!(" == modified Cargo.toml file ==");
println!("{:#?}", update_content);
// write the modified Cargo.toml file back to disk
//fs::write(cargo_toml_path, update_content).context("Failed to write Cargo.toml")?;
Ok(())
}
/*
Cargo.toml file content:
[package]
name = "task3"
version = "0.1.0"
edition = "2021"
[dependencies]
toml = "0.7"
serde = { version = "1.0", features = ["derive"] }
anyhow = "1.0"
*/
来看看我的最终结果吧
看看,虽然不算完美,但也算是一个历程,后续继续加油!!