From 9a16557016493a602f8951751e9a2f3cae509578 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 21 Aug 2022 12:48:47 +0300 Subject: [PATCH] repo: remove fs implementation Closes #34 --- Cargo.lock | 39 ------ Cargo.toml | 2 - src/bin/fs_to_sqlite.rs | 61 --------- src/cli/add.rs | 1 - src/cli/priority.rs | 1 - src/repo.rs | 2 - src/repo/fs.rs | 268 ---------------------------------------- src/repo/sqlite.rs | 8 +- 8 files changed, 2 insertions(+), 380 deletions(-) delete mode 100644 src/bin/fs_to_sqlite.rs delete mode 100644 src/repo/fs.rs diff --git a/Cargo.lock b/Cargo.lock index 1c399dc..5923724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,43 +286,6 @@ dependencies = [ "time", ] -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "serde" -version = "1.0.142" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.142" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "smallvec" version = "1.9.0" @@ -347,8 +310,6 @@ dependencies = [ "clap", "log", "rusqlite", - "serde", - "serde_json", "time", "xdg", ] diff --git a/Cargo.toml b/Cargo.toml index 7f45445..fb8a5d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,6 @@ maintenance = { status = "experimental" } clap = { version = "3.2.16", default-features = false, features = ["derive", "std"] } log = "0.4.17" rusqlite = { version = "0.28.0", features = ["bundled", "time"] } -serde = { version = "1.0.142", features = ["derive"] } -serde_json = "1.0.83" time = "0.3" xdg = "2.4.1" diff --git a/src/bin/fs_to_sqlite.rs b/src/bin/fs_to_sqlite.rs deleted file mode 100644 index 2c478f0..0000000 --- a/src/bin/fs_to_sqlite.rs +++ /dev/null @@ -1,61 +0,0 @@ -use tas::repo::{self, Repository}; -use xdg::BaseDirectories; - -fn main() { - let xdg_dirs = BaseDirectories::with_prefix(env!("CARGO_PKG_NAME")).unwrap(); - let fs_repo = repo::fs::FsRepo::new(xdg_dirs.clone()); - let sqlite_repo = repo::sqlite::SqliteRepo::new(xdg_dirs.clone()).unwrap(); - - log::info!("active tasks"); - - let fs_tasks = fs_repo.get_tasks(false).unwrap(); - if !fs_tasks.is_empty() { - for task in fs_tasks { - log::info!("task: {}", task.name); - log::info!(" inserting..."); - - sqlite_repo - .insert_task(repo::InsertTaskData { - name: task.name, - project: task.project, - link: task.link, - dir_path: task.dir_path, - index: None, - finished_at: None, - }) - .unwrap(); - - log::info!(" inserted"); - } - } - - log::info!("finished tasks"); - - let fs_tasks = fs_repo.get_tasks(true).unwrap(); - if !fs_tasks.is_empty() { - let meta = std::fs::metadata(xdg_dirs.get_data_file(repo::fs::FINISHED_DATA_FILE)).unwrap(); - let finished_at = meta - .modified() - .map(time::OffsetDateTime::from) - .unwrap_or_else(|_| time::OffsetDateTime::now_utc()); - - for task in fs_tasks { - log::info!("task: {}", task.name); - log::info!(" inserting..."); - - sqlite_repo - .insert_task(repo::InsertTaskData { - name: task.name, - project: task.project, - link: task.link, - dir_path: task.dir_path, - index: None, - finished_at: Some(finished_at), - }) - // TODO: think of a better solution than idx - .ok(); - - log::info!(" inserted"); - } - } -} diff --git a/src/cli/add.rs b/src/cli/add.rs index 94434ca..bd3373b 100644 --- a/src/cli/add.rs +++ b/src/cli/add.rs @@ -43,7 +43,6 @@ pub fn execute(repo: impl Repository, args: Args) { .transpose() .unwrap(), index: None, - finished_at: None, }); match res { diff --git a/src/cli/priority.rs b/src/cli/priority.rs index 2dc795b..5b360a8 100644 --- a/src/cli/priority.rs +++ b/src/cli/priority.rs @@ -77,7 +77,6 @@ pub fn execute(repo: impl Repository, args: Args) { project: target.project, link: target.link, dir_path: target.dir_path, - finished_at: None, }); match res { Ok(task) => { diff --git a/src/repo.rs b/src/repo.rs index d1bbd8e..4d72c04 100755 --- a/src/repo.rs +++ b/src/repo.rs @@ -13,7 +13,6 @@ //! You should have received a copy of the GNU General Public License //! along with tas. If not, see . //! -pub mod fs; pub mod sqlite; use std::path::PathBuf; @@ -55,7 +54,6 @@ pub struct InsertTaskData { pub link: Option, pub dir_path: Option, pub index: Option, - pub finished_at: Option, } pub struct UpdateTaskData { diff --git a/src/repo/fs.rs b/src/repo/fs.rs deleted file mode 100644 index 1ff14cd..0000000 --- a/src/repo/fs.rs +++ /dev/null @@ -1,268 +0,0 @@ -//! Copyright (C) 2022, Dmitriy Pleshevskiy -//! -//! tas is free software: you can redistribute it and/or modify -//! it under the terms of the GNU General Public License as published by -//! the Free Software Foundation, either version 3 of the License, or -//! (at your option) any later version. -//! -//! tas is distributed in the hope that it will be useful, -//! but WITHOUT ANY WARRANTY; without even the implied warranty of -//! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//! GNU General Public License for more details. -//! -//! You should have received a copy of the GNU General Public License -//! along with tas. If not, see . -//! -use std::fs::File; -use std::io::Write; -use std::path::PathBuf; - -use crate::domain; -use crate::repo::{Error, InsertTaskData, Repository, UpdateTaskData}; - -use serde::{Deserialize, Serialize}; -use xdg::BaseDirectories; - -#[derive(Deserialize, Serialize, Clone)] -pub struct Task { - name: String, - group: Option, - link: Option, - path: Option, - // created_at -} - -impl From for domain::Task { - fn from(repo: Task) -> Self { - domain::Task { - name: repo.name, - project: repo.group, - link: repo.link, - dir_path: repo.path.map(PathBuf::from), - created_at: time::OffsetDateTime::now_utc(), - } - } -} - -#[derive(Deserialize, Serialize, Clone)] -pub struct CurrentTaskInfo { - task_idx: usize, - task: Task, - // started_at -} - -impl From for domain::CurrentTaskInfo { - fn from(repo: CurrentTaskInfo) -> Self { - domain::CurrentTaskInfo { - task_idx: repo.task_idx, - task: repo.task.into(), - } - } -} - -pub const CURRENT_TASK_FILE: &str = "current.json"; -pub const DATA_FILE: &str = "data.json"; -pub const FINISHED_DATA_FILE: &str = "finished_data.json"; - -pub struct FsRepo { - xdg_dirs: BaseDirectories, -} - -impl FsRepo { - pub fn new(xdg_dirs: BaseDirectories) -> Self { - Self { xdg_dirs } - } -} - -impl Repository for FsRepo { - fn get_current_task_opt(&self) -> Result, Error> { - self.get_current_task_impl() - .map(|cur_task| cur_task.map(From::from)) - } - - fn get_task_opt(&self, id: domain::TaskIdx) -> Result, Error> { - let tasks = self.get_tasks_impl()?; - if id == 0 || id > tasks.len() { - return Err(Error::NotFound); - } - - Ok(Some(tasks[id - 1].clone().into())) - } - - fn get_tasks(&self, finished: bool) -> Result, Error> { - let fs_tasks = if finished { - self.get_finished_tasks_impl()?.into_iter().rev().collect() - } else { - self.get_tasks_impl()? - }; - - Ok(fs_tasks.into_iter().map(Task::into).collect()) - } - - fn remove_task(&self, id: domain::TaskIdx) -> Result { - let mut tasks = self.get_tasks_impl()?; - if id == 0 || id > tasks.len() { - return Err(Error::NotFound); - } - - let removed = tasks.remove(id - 1); - self.save_tasks_impl(tasks)?; - - Ok(removed.into()) - } - - fn update_task( - &self, - id: domain::TaskIdx, - update_data: UpdateTaskData, - ) -> Result { - let mut tasks = self.get_tasks_impl()?; - if id == 0 || id > tasks.len() { - return Err(Error::NotFound); - } - - let mut task = &mut tasks[id - 1]; - if let Some(name) = update_data.name { - task.name = name; - } - - if let Some(group) = update_data.project { - task.group = group; - } - - if let Some(link) = update_data.link { - task.link = link; - } - - if let Some(path) = update_data.dir_path { - task.path = path.and_then(|p| p.into_os_string().into_string().ok()); - } - - let new_task = task.clone(); - - self.save_tasks_impl(tasks)?; - - Ok(new_task.into()) - } - - fn insert_task(&self, insert_data: InsertTaskData) -> Result { - let new_task = Task { - name: insert_data.name, - group: insert_data.project, - link: insert_data.link, - path: insert_data - .dir_path - .and_then(|p| p.into_os_string().into_string().ok()), - }; - - let mut tasks = self.get_tasks_impl()?; - - match insert_data.index { - None => tasks.push(new_task.clone()), - Some(idx) => tasks.insert(idx, new_task.clone()), - } - - self.save_tasks_impl(tasks)?; - - Ok(new_task.into()) - } - - fn start_task(&self, id: domain::TaskIdx) -> Result { - let tasks = self.get_tasks_impl()?; - if id == 0 || id > tasks.len() { - return Err(Error::NotFound); - } - - let task = &tasks[id - 1]; - let mut cur_task = self.get_current_task_impl()?; - - cur_task.replace(CurrentTaskInfo { - task_idx: id, - task: task.clone(), - }); - - self.save_current_task_impl(cur_task)?; - Ok(task.clone().into()) - } - - fn stop_task(&self) -> Result { - let mut cur_task = self.get_current_task_impl()?; - let old = cur_task.take().ok_or(Error::NotFound)?; - self.save_current_task_impl(cur_task)?; - Ok(old.task.into()) - } - - fn finish_task(&self) -> Result { - let mut cur_task = self.get_current_task_impl()?; - let old = cur_task.take().ok_or(Error::NotFound)?; - - let mut finished_tasks = self.get_finished_tasks_impl()?; - let mut tasks = self.get_tasks_impl()?; - - let task = tasks.remove(old.task_idx - 1); - finished_tasks.push(task.clone()); - - self.save_current_task_impl(cur_task)?; - self.save_tasks_impl(tasks)?; - self.save_finished_tasks_impl(finished_tasks)?; - - Ok(task.into()) - } -} - -impl FsRepo { - fn get_current_task_impl(&self) -> Result, Error> { - let file_path = self.xdg_dirs.get_data_file(CURRENT_TASK_FILE); - Ok(File::open(&file_path) - .ok() - .and_then(|file| serde_json::from_reader(file).ok())) - } - - fn save_current_task_impl(&self, cur_task: Option) -> Result<(), Error> { - let file_path = self - .xdg_dirs - .place_data_file(CURRENT_TASK_FILE) - .map_err(|_| Error::InsertData)?; - let mut file = File::create(&file_path).map_err(|_| Error::InsertData)?; - let new_data = serde_json::to_vec(&cur_task).map_err(|_| Error::InvalidData)?; - file.write_all(&new_data).map_err(|_| Error::InsertData) - } - - fn get_tasks_impl(&self) -> Result, Error> { - let file_path = self.xdg_dirs.get_data_file(DATA_FILE); - File::open(&file_path) - .ok() - .map(|file| serde_json::from_reader(file).map_err(|_| Error::InvalidData)) - .transpose() - .map(|tasks| tasks.unwrap_or_default()) - } - - fn save_tasks_impl(&self, tasks: Vec) -> Result<(), Error> { - let file_path = self - .xdg_dirs - .place_data_file(DATA_FILE) - .map_err(|_| Error::InsertData)?; - let mut file = File::create(&file_path).map_err(|_| Error::InsertData)?; - let new_data = serde_json::to_vec(&tasks).map_err(|_| Error::InvalidData)?; - file.write_all(&new_data).map_err(|_| Error::InsertData) - } - - fn get_finished_tasks_impl(&self) -> Result, Error> { - let file_path = self.xdg_dirs.get_data_file(FINISHED_DATA_FILE); - File::open(&file_path) - .ok() - .map(|file| serde_json::from_reader(file).map_err(|_| Error::InvalidData)) - .transpose() - .map(|tasks| tasks.unwrap_or_default()) - } - - fn save_finished_tasks_impl(&self, tasks: Vec) -> Result<(), Error> { - let file_path = self - .xdg_dirs - .place_data_file(FINISHED_DATA_FILE) - .map_err(|_| Error::InsertData)?; - let mut file = File::create(&file_path).map_err(|_| Error::InsertData)?; - let new_data = serde_json::to_vec(&tasks).map_err(|_| Error::InvalidData)?; - file.write_all(&new_data).map_err(|_| Error::InsertData) - } -} diff --git a/src/repo/sqlite.rs b/src/repo/sqlite.rs index 650fb6a..5e09e4a 100644 --- a/src/repo/sqlite.rs +++ b/src/repo/sqlite.rs @@ -121,8 +121,8 @@ impl Repository for SqliteRepo { let mut stmt = self .conn .prepare( - "INSERT INTO tasks (name, project, link, dir_path, created_at, finished_at) - VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + "INSERT INTO tasks (name, project, link, dir_path) + VALUES (?1, ?2, ?3, ?4)", ) .map_err(|_| Error::PrepareQuery)?; @@ -134,10 +134,6 @@ impl Repository for SqliteRepo { &insert_data .dir_path .and_then(|p| p.into_os_string().into_string().ok()), - &insert_data - .finished_at - .unwrap_or_else(|| time::OffsetDateTime::now_utc()), - &insert_data.finished_at, )) .map_err(|_| Error::InsertData)?;