Day 6:檔案儲存與讀取(持久化)

學習目標

  • 用 serde_json 序列化任務到檔案
  • 啟動時載入既有任務
  • 建構完整可持久化的 store

今日重點

載入 / 儲存

use std::fs;
use std::path::Path;

const DATA_FILE: &str = "todo.json";

impl TaskStore {
    fn load(path: &str) -> TaskStore {
        match fs::read_to_string(path) {
            Ok(contents) => {
                let tasks: Vec<Task> = serde_json::from_str(&contents).unwrap_or_default();
                let next_id = tasks.iter().map(|t| t.id + 1).max().unwrap_or(1);
                TaskStore { tasks, next_id }
            }
            Err(_) => TaskStore::new(),   // 沒有檔案就從空開始
        }
    }

    fn save(&self, path: &str) -> Result<(), std::io::Error> {
        let json = serde_json::to_string_pretty(&self.tasks).unwrap();
        fs::write(path, json)
    }
}

main 整合(每次操作前載入、後儲存)

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let cli = Cli::parse();
    let mut store = TaskStore::load(DATA_FILE);

    match cli.command {
        Command::Add { title } => { store.add(title); println!("已新增"); }
        Command::List => print_list(&store.tasks),
        Command::Done { id } => { /* 改 done */ }
        Command::Remove { id } => { /* 刪除 */ }
    }

    store.save(DATA_FILE)?;   // 存回檔案
    Ok(())
}

練習

  1. 完成 load / save 並整合進 main。
  2. 測試「新增後重開程式,任務還在」。
  3. 檢查 todo.json 的內容是美觀的 JSON。

自我檢查

  • 能把任務存成 JSON
  • 能從 JSON 載回任務
  • 重開程式資料仍保留
  • 持久化完成

深入連結

  • serde_json 文件(to_string_pretty, from_str)