记录一次AI让我砸键盘的折寿行为。
最近在用 AI 来辅助学习 Rust 编程,想完成一个功能,读取 config.toml 配置文件,内容格式如下:
toml
[dev]
username = "tester1"
password = "******"
[prod]
username = "tester2"
password = "******"
功能需要满足以下要求:
- 如果能找到对应的配置,写入时直接更新
- 如果找不到,则创建一个新的配置块,写入到文件最后
- 新插入的配置块不能影响原有的配置顺序
实现了如下接口 write_target
,使用的是 toml
这个库,但是这个库做序列化写入的时候不能满足第三点需求(顺序是变的)
咨询AI,说是可以用 toml_edit
来实现这一要求,于是把上面的需求作为提示词给了 AI,让他用 toml_edit
帮我重新实现 write_target
这个函数。
经过几十轮的修改,最终还是没实现,代码都编译不过。(主要原因还是我菜,此处:狗头保命)
尝试过 Trae
, Cursor
,都没有一个能写出来通过编译的。(此处,跪求掘金大佬指点)
rust
#[derive(Serialize, Deserialize, Debug, Default)]
struct Config {
#[serde(flatten)]
targets: std::collections::HashMap<String, Target>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Target {
username: String,
password: String,
}
fn write_target(target: &String, username: &String, password: &String) {
let mut config_path = home_dir().expect("无法访问Home目录");
config_path.push(".config/yt/config.toml");
let mut config: Config;
if config_path.exists() {
let content = fs::read_to_string(&config_path).unwrap();
config = toml::from_str(&content).unwrap();
} else {
println!("配置文件不存在");
fs::create_dir_all(config_path.parent().unwrap()).unwrap();
config = Config::default();
}
let item = config.targets.get_mut(target);
match item {
Some(target) => {
target.username = username.clone();
target.password = password.clone();
}
None => {
config.targets.insert(target.clone(), Target { username: username.clone(), password: password.clone() });
}
}
match fs::write(config_path, toml::to_string(&config).unwrap()) {
Ok(_) => {
println!("写入配置文件成功");
}
Err(e) => {
eprintln!("写入配置文件失败: {}", e);
}
}
}
后面翻 toml_edit
的文档:crates.io/crates/toml..., 看到示例中使用了 DocumentMut
,于是亲自动手来修改 write_taget
方法,居然成功了。
简化后的代码:
rust
fn write_target(target: &String, username: &String, password: &String) {
let mut config_path = home_dir().expect("无法访问Home目录");
config_path.push(".config/yt/config.toml");
let content = if config_path.exists() {
fs::read_to_string(&config_path).unwrap()
} else {
String::new()
};
let mut doc = content.parse::<DocumentMut>().unwrap();
let mut new_table = Table::new();
new_table.insert("username", Item::Value(Value::from(username)));
new_table.insert("password", Item::Value(Value::from(password)));
doc[target] = Item::Table(new_table);
fs::write(config_path, doc.to_string()).unwrap();
println!("写入配置文件成功");
}