adds DB rw

adds dependencies

adds models derivations
This commit is contained in:
itsscb 2024-08-04 22:16:47 +02:00
parent 79c739ad77
commit 148ca03686
4 changed files with 62 additions and 15 deletions

View File

@ -4,3 +4,9 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.86"
serde = {version = "1.0.204", features = ["derive"]}
serde_json = "1.0.122"
[dev-dependencies]
tempfile = "3.11.0"

View File

@ -1,6 +1,8 @@
use std::fs;
use anyhow::Result; use anyhow::Result;
use crate::models::{DBState, Epic, Story, Status}; use crate::models::{DBState, Epic, Status, Story};
trait Database { trait Database {
fn read_db(&self) -> Result<DBState>; fn read_db(&self) -> Result<DBState>;
@ -8,16 +10,19 @@ trait Database {
} }
struct JSONFileDatabase { struct JSONFileDatabase {
pub file_path: String pub file_path: String,
} }
impl Database for JSONFileDatabase { impl Database for JSONFileDatabase {
fn read_db(&self) -> Result<DBState> { fn read_db(&self) -> Result<DBState> {
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<()> { 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] #[test]
fn read_db_should_fail_with_invalid_path() { 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); assert_eq!(db.read_db().is_err(), true);
} }
@ -44,8 +51,13 @@ mod tests {
let file_contents = r#"{ "last_item_id": 0 epics: {} stories {} }"#; let file_contents = r#"{ "last_item_id": 0 epics: {} stories {} }"#;
write!(tmpfile, "{}", file_contents).unwrap(); write!(tmpfile, "{}", file_contents).unwrap();
let db = JSONFileDatabase { file_path: tmpfile.path().to_str() let db = JSONFileDatabase {
.expect("failed to convert tmpfile path to str").to_string() }; file_path: tmpfile
.path()
.to_str()
.expect("failed to convert tmpfile path to str")
.to_string(),
};
let result = db.read_db(); let result = db.read_db();
@ -59,8 +71,13 @@ mod tests {
let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#; let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#;
write!(tmpfile, "{}", file_contents).unwrap(); write!(tmpfile, "{}", file_contents).unwrap();
let db = JSONFileDatabase { file_path: tmpfile.path().to_str() let db = JSONFileDatabase {
.expect("failed to convert tmpfile path to str").to_string() }; file_path: tmpfile
.path()
.to_str()
.expect("failed to convert tmpfile path to str")
.to_string(),
};
let result = db.read_db(); let result = db.read_db();
@ -74,11 +91,25 @@ mod tests {
let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#; let file_contents = r#"{ "last_item_id": 0, "epics": {}, "stories": {} }"#;
write!(tmpfile, "{}", file_contents).unwrap(); write!(tmpfile, "{}", file_contents).unwrap();
let db = JSONFileDatabase { file_path: tmpfile.path().to_str() let db = JSONFileDatabase {
.expect("failed to convert tmpfile path to str").to_string() }; 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 story = Story {
let epic = Epic { name: "epic 1".to_owned(), description: "epic 1".to_owned(), status: Status::Open, stories: vec![2] }; 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(); let mut stories = HashMap::new();
stories.insert(2, story); stories.insert(2, story);
@ -86,7 +117,11 @@ mod tests {
let mut epics = HashMap::new(); let mut epics = HashMap::new();
epics.insert(1, epic); 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 write_result = db.write_db(&state);
let read_result = db.read_db().unwrap(); let read_result = db.read_db().unwrap();
@ -96,4 +131,4 @@ mod tests {
assert_eq!(read_result, state); assert_eq!(read_result, state);
} }
} }
} }

View File

@ -1,4 +1,5 @@
mod models; mod models;
mod db;
fn main() { fn main() {
println!("Welcome scrumtask-cli!"); println!("Welcome scrumtask-cli!");

View File

@ -1,5 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Status { pub enum Status {
Open, Open,
InProgress, InProgress,
@ -7,6 +9,7 @@ pub enum Status {
Closed, Closed,
} }
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Epic { pub struct Epic {
pub name: String, pub name: String,
pub description: String, pub description: String,
@ -25,6 +28,7 @@ impl Epic {
} }
} }
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Story { pub struct Story {
pub name: String, pub name: String,
pub description: String, pub description: String,
@ -41,6 +45,7 @@ impl Story {
} }
} }
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct DBState { pub struct DBState {
pub last_item_id: u32, pub last_item_id: u32,
pub epics: HashMap<u32, Epic>, pub epics: HashMap<u32, Epic>,