不懂装懂的AI,折了程序员的阳寿

记录一次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!("写入配置文件成功");
}
相关推荐
2301_7965125218 分钟前
Rust编程学习 - 如何利用代数类型系统做错误处理的另外一大好处是可组合性(composability)
java·学习·rust
星释1 小时前
Rust 练习册 :Proverb与字符串处理
开发语言·后端·rust
Source.Liu1 小时前
【ISO8601库】Serde 集成模块详解(serde.rs文件)
rust·time·iso8601
星释3 小时前
Rust 练习册 :Pig Latin与语言游戏
游戏·rust·c#
2301_795167203 小时前
玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
开发语言·后端·算法·安全·rust
ftpeak5 小时前
《Rust+Slint:跨平台GUI应用》第八章 窗体
开发语言·ui·rust·slint
百锦再8 小时前
第10章 错误处理
java·git·ai·rust·go·错误·pathon
2301_7951672010 小时前
玩转Rust高级应用. ToOwned trait 提供的是一种更“泛化”的Clone 的功能,Clone一般是从&T类型变量创造一个新的T类型变量
开发语言·后端·rust
星释10 小时前
Rust 练习册 :Phone Number与电话号码处理
开发语言·机器学习·rust
2301_7965125211 小时前
Rust编程学习 - 问号运算符会return一个Result 类型,但是如何使用main函数中使用问号运算符
开发语言·学习·算法·rust