taskman 0.1.0

Cli for the task management.
use std::fs::{self, File, OpenOptions};
use std::io::{self, BufReader, BufWriter, prelude::*};

use crate::domain::{CreateTaskRequest, Task};
use crate::persister::deserialize;
use crate::persister::serialize;

pub(crate) fn get_tasks(page_number: Option<usize>, page_size: Option<usize>) -> Vec<Task> {
    let tasks_file = get_file();
    let buff_reader = BufReader::new(tasks_file);
    let tasks = buff_reader
        .lines()
        .map(|l| l.unwrap())
        .filter(|l| !l.is_empty())
        .map(|l| deserialize(&l).unwrap())
        .filter(|vec| {
            let is_deleted = vec.get(3).unwrap().as_ref().unwrap();
            is_deleted == "0"
        })
        .map(|ts| Task {
            id: ts.get(0).unwrap().as_ref().unwrap().parse().unwrap(),
            name: ts.get(1).unwrap().as_ref().unwrap().to_string(),
            description: ts.get(2).unwrap().as_ref().map(|t| t.to_string()),
        })
        .collect::<Vec<Task>>();
    tasks
}

pub(crate) fn get_tasks_by_name(name: &str) -> Vec<Task> {
    get_tasks(None, None)
        .into_iter()
        .filter(|task| task.name.as_str() == name)
        .collect()
}

pub(crate) fn delete_task(task_id: u64) {
    let mut home_path = home::home_dir().unwrap().to_path_buf();
    home_path.push(".taskman");
    home_path.push("tasks");
    let tasks_path = home_path.as_path();
    let mut home_path2 = home::home_dir().unwrap().to_path_buf();
    home_path2.push(".taskman");
    home_path2.push("tasks.temp");
    let temp_file = OpenOptions::new()
        .write(true)
        .create(true)
        .append(false)
        .truncate(true)
        .open(home_path2.as_path())
        .map_err(|e| PersisterError::FilePersisterError(e))
        .unwrap();
    let read_file = File::open(tasks_path)
        .map_err(|e| PersisterError::FileNotFound(e))
        .unwrap();
    let file = BufReader::new(read_file);
    let mut buf_writer = BufWriter::new(temp_file);
    for line in file.lines() {
        let line = line.unwrap();
        if line.is_empty() {
            continue;
        }
        let des = deserialize(&line).unwrap();
        let des_task_id: u64 = des.get(0).unwrap().as_ref().unwrap().parse().unwrap();
        if des_task_id != task_id {
            writeln!(&mut buf_writer, "{line}").unwrap();
        }
    }
    fs::rename(home_path2.as_path(), home_path.as_path()).unwrap();
}

#[derive(Debug)]
pub(crate) enum PersisterError {
    FilePersisterError(io::Error),
    TaskNotFound,
    FileNotFound(io::Error),
}

pub(crate) fn save_task(task: &CreateTaskRequest) {
    let vec = vec![
        Some(task.id.to_string()),
        Some(task.name.clone()),
        task.description.clone(),
        Some("0".to_string()),
    ];
    let str = serialize(&vec);
    let file = get_file();
    writeln!(&file, "{str}").unwrap();
}

fn get_file() -> File {
    let mut home_path = home::home_dir().unwrap().to_path_buf();
    home_path.push(".taskman");
    home_path.push("tasks");
    let tasks_path = home_path.as_path();
    fs::create_dir_all(tasks_path.parent().unwrap()).unwrap();
    OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .append(true)
        .truncate(false)
        .open(tasks_path)
        .unwrap()
}