use serde::{Deserialize, Serialize};
use std::path::Path;
use std::fs;
use chrono::prelude::*;
use uuid::Uuid;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum TaskError {
#[error("Task not found")]
TaskNotFound,
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum Priority {
Low,
Medium,
High,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task {
pub id: String,
pub description: String,
pub priority: Priority,
pub created_at: DateTime<Utc>,
pub completed: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TaskManager {
tasks: Vec<Task>,
}
impl TaskManager {
pub fn new() -> Self {
TaskManager { tasks: Vec::new() }
}
pub fn add_task(&mut self, description: &str, priority: Priority) -> Result<(), TaskError> {
let task = Task {
id: Uuid::new_v4().to_string(),
description: description.to_string(),
priority,
created_at: Utc::now(),
completed: false,
};
self.tasks.push(task);
Ok(())
}
pub fn complete_task(&mut self, index: usize) -> Result<(), TaskError> {
if let Some(task) = self.tasks.get_mut(index) {
task.completed = true;
Ok(())
} else {
Err(TaskError::TaskNotFound)
}
}
pub fn tasks(&self) -> &Vec<Task> {
&self.tasks
}
pub fn save_to_file(&self, path: &Path) -> Result<(), TaskError> {
let serialized = serde_json::to_string_pretty(&self)?;
fs::write(path, serialized)?;
Ok(())
}
pub fn load_from_file(path: &Path) -> Result<Self, TaskError> {
let contents = fs::read_to_string(path)?;
let manager = serde_json::from_str(&contents)?;
Ok(manager)
}
}
impl Default for TaskManager {
fn default() -> Self {
Self::new()
}
}