تمرين إعادة البناء
Todo List Manager
أعد كتابة مدير مهام صغير يضيف ويعرض ويؤشر المهام في ملف نصي.
rust
~16 دقيقة
مبتدئ
أعد بناء الكود
Rebuild
هذا هو الكود. اكتبه بنفسك.
الكود المرجعي
use std::env;
use std::fs;
use std::io;
use std::path::Path;
const TODO_FILE: &str = "todos.txt";
fn main() -> io::Result<()> {
let mut args = env::args().skip(1);
let command = args.next().unwrap_or_else(|| "list".to_string());
match command.as_str() {
"add" => {
let text = args.collect::<Vec<_>>().join(" ");
if text.is_empty() {
println!("Usage: todo add buy milk");
} else {
let mut tasks = load_tasks()?;
tasks.push(Task { done: false, text });
save_tasks(&tasks)?;
}
}
"done" => {
let number = args.next().and_then(|value| value.parse::<usize>().ok());
if let Some(index) = number.and_then(|n| n.checked_sub(1)) {
let mut tasks = load_tasks()?;
if let Some(task) = tasks.get_mut(index) {
task.done = true;
save_tasks(&tasks)?;
}
}
}
"list" => print_tasks(&load_tasks()?),
_ => println!("Commands: add, done, list"),
}
Ok(())
}
#[derive(Clone)]
struct Task {
done: bool,
text: String,
}
fn load_tasks() -> io::Result<Vec<Task>> {
if !Path::new(TODO_FILE).exists() {
return Ok(Vec::new());
}
let text = fs::read_to_string(TODO_FILE)?;
let tasks = text
.lines()
.map(|line| Task {
done: line.starts_with("[x] "),
text: line.get(4..).unwrap_or("").to_string(),
})
.collect();
Ok(tasks)
}
fn save_tasks(tasks: &[Task]) -> io::Result<()> {
let mut text = String::new();
for task in tasks {
let mark = if task.done { "[x]" } else { "[ ]" };
text.push_str(&format!("{mark} {}\n", task.text));
}
fs::write(TODO_FILE, text)
}
fn print_tasks(tasks: &[Task]) {
for (index, task) in tasks.iter().enumerate() {
let mark = if task.done { "x" } else { " " };
println!("{}. [{mark}] {}", index + 1, task.text);
}
}اكتب هنا