From 148ca0368609c7d5117fc97f18ec4e81712b29c1 Mon Sep 17 00:00:00 2001 From: itsscb Date: Sun, 4 Aug 2024 22:16:47 +0200 Subject: [PATCH] adds DB rw adds dependencies adds models derivations --- Cargo.toml | 6 +++++ src/db.rs | 65 +++++++++++++++++++++++++++++++++++++++------------ src/main.rs | 1 + src/models.rs | 5 ++++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 73671b0..77dd2ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.86" +serde = {version = "1.0.204", features = ["derive"]} +serde_json = "1.0.122" + +[dev-dependencies] +tempfile = "3.11.0" diff --git a/src/db.rs b/src/db.rs index d0054ce..142c8cc 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,8 @@ +use std::fs; + use anyhow::Result; -use crate::models::{DBState, Epic, Story, Status}; +use crate::models::{DBState, Epic, Status, Story}; trait Database { fn read_db(&self) -> Result; @@ -8,16 +10,19 @@ trait Database { } struct JSONFileDatabase { - pub file_path: String + pub file_path: String, } impl Database for JSONFileDatabase { fn read_db(&self) -> Result { - todo!() // read the content's of self.file_path and deserialize it using serde + let contents = fs::read_to_string(&self.file_path)?; + let db: DBState = serde_json::from_str(&contents)?; + Ok(db) } fn write_db(&self, db_state: &DBState) -> Result<()> { - todo!() // serialize db_state to json and store it in self.file_path + let state = serde_json::to_vec_pretty(&db_state)?; + Ok(fs::write(&self.file_path, state)?) } } @@ -33,7 +38,9 @@ mod tests { #[test] fn read_db_should_fail_with_invalid_path() { - let db = JSONFileDatabase { file_path: "INVALID_PATH".to_owned() }; + let db = JSONFileDatabase { + file_path: "INVALID_PATH".to_owned(), + }; assert_eq!(db.read_db().is_err(), true); } @@ -44,8 +51,13 @@ mod tests { let file_contents = r#"{ "last_item_id": 0 epics: {} stories {} }"#; write!(tmpfile, "{}", file_contents).unwrap(); - let db = JSONFileDatabase { file_path: tmpfile.path().to_str() - .expect("failed to convert tmpfile path to str").to_string() }; + let db = JSONFileDatabase { + file_path: tmpfile + .path() + .to_str() + .expect("failed to convert tmpfile path to str") + .to_string(), + }; let result = db.read_db(); @@ -59,8 +71,13 @@ mod tests { let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#; write!(tmpfile, "{}", file_contents).unwrap(); - let db = JSONFileDatabase { file_path: tmpfile.path().to_str() - .expect("failed to convert tmpfile path to str").to_string() }; + let db = JSONFileDatabase { + file_path: tmpfile + .path() + .to_str() + .expect("failed to convert tmpfile path to str") + .to_string(), + }; let result = db.read_db(); @@ -74,11 +91,25 @@ mod tests { let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#; write!(tmpfile, "{}", file_contents).unwrap(); - let db = JSONFileDatabase { file_path: tmpfile.path().to_str() - .expect("failed to convert tmpfile path to str").to_string() }; + let db = JSONFileDatabase { + file_path: tmpfile + .path() + .to_str() + .expect("failed to convert tmpfile path to str") + .to_string(), + }; - let story = Story { name: "epic 1".to_owned(), description: "epic 1".to_owned(), status: Status::Open }; - let epic = Epic { name: "epic 1".to_owned(), description: "epic 1".to_owned(), status: Status::Open, stories: vec![2] }; + let story = Story { + name: "epic 1".to_owned(), + description: "epic 1".to_owned(), + status: Status::Open, + }; + let epic = Epic { + name: "epic 1".to_owned(), + description: "epic 1".to_owned(), + status: Status::Open, + stories: vec![2], + }; let mut stories = HashMap::new(); stories.insert(2, story); @@ -86,7 +117,11 @@ mod tests { let mut epics = HashMap::new(); epics.insert(1, epic); - let state = DBState { last_item_id: 2, epics, stories }; + let state = DBState { + last_item_id: 2, + epics, + stories, + }; let write_result = db.write_db(&state); let read_result = db.read_db().unwrap(); @@ -96,4 +131,4 @@ mod tests { assert_eq!(read_result, state); } } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 3002e65..fde5ef3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod models; +mod db; fn main() { println!("Welcome scrumtask-cli!"); diff --git a/src/models.rs b/src/models.rs index c1e957f..0f5a471 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,5 +1,7 @@ use std::collections::HashMap; +use serde::{Deserialize, Serialize}; +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum Status { Open, InProgress, @@ -7,6 +9,7 @@ pub enum Status { Closed, } +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Epic { pub name: String, pub description: String, @@ -25,6 +28,7 @@ impl Epic { } } +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Story { pub name: String, pub description: String, @@ -41,6 +45,7 @@ impl Story { } } +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct DBState { pub last_item_id: u32, pub epics: HashMap,