repo: add update data method

This commit is contained in:
Dmitriy Pleshevskiy 2022-08-05 23:40:26 +03:00
parent 8934f4ceef
commit 4dbfe41e84
Signed by: pleshevskiy
GPG key ID: 1B59187B161C0215
6 changed files with 82 additions and 39 deletions

View file

@ -16,14 +16,14 @@ pub fn execute(repo: impl Repository, args: Args) {
match res {
Ok(task) => {
println!("Task was added successfully");
println!("The task was added successfully");
println!(" {}", task.name);
if let Some(link) = task.link {
println!(" link: {}", link);
}
}
Err(err) => {
eprintln!("Cannot insert data: {}", err);
eprintln!("Cannot insert a new task: {}", err);
}
}

View file

@ -1,7 +1,7 @@
use std::io::Write;
use std::path::PathBuf;
use crate::{CurrentTaskInfo, Task};
use crate::repo::{self, Repository};
use crate::CurrentTaskInfo;
#[derive(clap::Args)]
pub struct Args {
@ -19,33 +19,32 @@ pub struct Args {
pub struct Request {
pub args: Args,
pub current_task_info: Option<CurrentTaskInfo>,
pub tasks: Vec<Task>,
pub tasks_file_path: PathBuf,
}
pub fn execute(mut req: Request) {
pub fn execute(repo: impl Repository, mut req: Request) {
if req.current_task_info.is_some() {
panic!("You can edit task only when you don't have an active task, yet");
}
let idx = req.args.idx;
if idx == 0 || idx > req.tasks.len() {
panic!("invalid index");
}
let args = req.args;
let mut task = &mut req.tasks[idx - 1];
if let Some(name) = req.args.name {
task.name = name;
let res = repo.update_task(
args.idx,
repo::UpdateTaskData {
name: args.name,
link: args.no_link.then(|| None).or(args.link.map(Some)),
},
);
match res {
Ok(task) => {
println!("The task was changed successfully");
println!(" {}", task.name);
if let Some(link) = task.link {
println!(" link: {}", link);
}
}
Err(err) => {
eprintln!("Cannot update the task: {}", err);
}
if let Some(link) = req.args.link {
task.link = Some(link);
} else if req.args.no_link {
task.link = None;
}
let mut file = std::fs::File::create(&req.tasks_file_path).unwrap();
file.write_all(&serde_json::to_vec(&req.tasks).unwrap())
.unwrap();
println!("changed");
}

View file

@ -1,3 +1,5 @@
pub type TaskId = usize;
pub struct Task {
pub name: String,
pub link: Option<String>,

View file

@ -55,12 +55,13 @@ fn main() {
cli::add::execute(repo, args);
}
cli::SubCommand::Edit(args) => {
cli::edit::execute(cli::edit::Request {
cli::edit::execute(
repo,
cli::edit::Request {
args,
current_task_info,
tasks,
tasks_file_path,
});
},
);
}
cli::SubCommand::Remove(args) => {
cli::remove::execute(cli::remove::Request {

View file

@ -26,8 +26,19 @@ pub struct InsertTaskData {
link: Option<String>,
}
pub struct UpdateTaskData {
name: Option<String>,
link: Option<Option<String>>,
}
pub trait Repository {
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error>;
fn update_task(
&self,
id: domain::TaskId,
update_data: UpdateTaskData,
) -> Result<domain::Task, Error>;
fn insert_task(&self, insert_data: InsertTaskData) -> Result<domain::Task, Error>;
}

View file

@ -2,7 +2,7 @@ use std::fs::File;
use std::io::Write;
use crate::domain;
use crate::repo::{Error, InsertTaskData, Repository};
use crate::repo::{Error, InsertTaskData, Repository, UpdateTaskData};
use serde::{Deserialize, Serialize};
use xdg::BaseDirectories;
@ -41,6 +41,32 @@ impl Repository for FsRepo {
.map(|tasks| tasks.into_iter().map(Task::into).collect())
}
fn update_task(
&self,
id: domain::TaskId,
update_data: UpdateTaskData,
) -> Result<domain::Task, Error> {
let mut tasks = self.get_tasks_impl()?;
if id == 0 || id > tasks.len() {
return Err(Error::NotFound);
}
let mut task = &mut tasks[id];
if let Some(name) = update_data.name {
task.name = name;
}
if let Some(link) = update_data.link {
task.link = link;
}
let new_task = task.clone();
self.save_tasks_impl(tasks)?;
Ok(new_task.into())
}
fn insert_task(&self, insert_data: InsertTaskData) -> Result<domain::Task, Error> {
let new_task = Task {
name: insert_data.name,
@ -50,13 +76,7 @@ impl Repository for FsRepo {
let mut tasks = self.get_tasks_impl()?;
tasks.push(new_task.clone());
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);
self.save_tasks_impl(tasks)?;
Ok(new_task.into())
}
@ -69,4 +89,14 @@ impl FsRepo {
.map_err(|_| Error::NotFound)
.and_then(|file| serde_json::from_reader(file).map_err(|_| Error::InvalidData))
}
fn save_tasks_impl(&self, tasks: Vec<Task>) -> 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)
}
}