Advertisement
IslandPenguin

task.rs

Mar 24th, 2021
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.74 KB | None | 0 0
  1. use chrono::{serde::ts_seconds, DateTime, Local, Utc};
  2. use serde::Deserialize;
  3. use serde::Serialize;
  4. use std::fmt;
  5. use std::fs::{File, OpenOptions};
  6. use std::io::{Error, Errorkind, Result, Seek, SeekFrom}; // Include the error type
  7. use std::PathBuf;
  8.  
  9. #[derive(Debug, Deserialize, Serialize)]
  10. pub struct Tasks {
  11.     pub text: String,
  12.  
  13.     #[serde(with = "ts_seconds")]
  14.     pub created_at: DateTime<Utc>,
  15. }
  16. impl Task {
  17.     pub fn new(text: String) -> Task {
  18.         let created_at: DateTime<Utc> = Utc::now();
  19.         Task { text, created_at }
  20.     }
  21. }
  22.  
  23. fn collect_tasks(mut file: &File) -> Result<Vec<Task>> {
  24.     file.seek(SeekFrom::Start(0))?; // Rewind the file before.
  25.     let tasks = match serde_json::from_reader(file) {
  26.         Ok(tasks) => tasks,
  27.         Err(e) if e.is_eof() => Vec::new(),
  28.         Err(e) => Err(e)?,
  29.     };
  30.  
  31.     file.seek(SeekFrom::Start(0))?; // Rewind the file after.
  32.     Ok(tasks)
  33. }
  34.  
  35. pub fn add_task(todo_path: PathBuf, task: Task) -> Result<()> {
  36.     // Open the file.
  37.     let file = OpenOptions::new()
  38.         .read(true)
  39.         .write(true)
  40.         .create(true)
  41.         .open(todo_path)?;
  42.  
  43.     // Consume the file's contents as a vector of tasks.
  44.     let mut tasks = collect_tasks(&file);
  45.  
  46.     // Write the modified task list back into the file.
  47.     tasks.push(task);
  48.     serde_json::to_writer(file, &tasks)?;
  49.  
  50.     Ok(())
  51. }
  52.  
  53. pub fn complete_task(todo_path: PathBuf, task_position: usize) -> Result<()> {
  54.     // Open the file.
  55.     let file = OpenOptions::new().read(true).write(true).open(todo_path)?;
  56.  
  57.     // Consume the file's contents as a vector of tasks.
  58.     let tasks = collect_tasks(file);
  59.  
  60.     // Remove the task.
  61.     if task_position == 0 || task_position > tasks.len() {
  62.         return Err(Error::new(ErrorKind::InvalidInput, "Invalid Task ID"));
  63.     }
  64.     tasks.remove(task_position - 1);
  65.     file.set_len(0)?;
  66.  
  67.     // Write the modified task list back into the file.
  68.     serde_json::to_writer(file, &tasks)?;
  69.     Ok(())
  70. }
  71.  
  72. pub fn list_tasks(todo_path: PathBuf) -> Result<()> {
  73.     // Open the file.
  74.     let file = OpenOptions::new().read(true).open(todo_path)?;
  75.     // Parse the file and collect the tasks.
  76.     let tasks = collect_tasks(&file)?;
  77.  
  78.     // Enumerate and display tasks, if any.
  79.     if tasks.is_empty() {
  80.         println!("Task list is empty!");
  81.     } else {
  82.         let mut order: u32 = 1;
  83.         for task in tasks {
  84.             println!("{}: {}", order, task);
  85.             order += 1;
  86.         }
  87.     }
  88.  
  89.     Ok(())
  90. }
  91.  
  92. impl fmt::Display for Task {
  93.     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  94.        let created_at = self.created_at.with_timezone(&Local).format("%F %H:%M");
  95.        write!(f, "{:<50} [{}]", self.text, created_at)
  96.    }
  97. }
  98.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement