Repo: move all methods to repository #14
6 changed files with 82 additions and 39 deletions
|
@ -16,14 +16,14 @@ pub fn execute(repo: impl Repository, args: Args) {
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(task) => {
|
Ok(task) => {
|
||||||
println!("Task was added successfully");
|
println!("The task was added successfully");
|
||||||
println!(" {}", task.name);
|
println!(" {}", task.name);
|
||||||
if let Some(link) = task.link {
|
if let Some(link) = task.link {
|
||||||
println!(" link: {}", link);
|
println!(" link: {}", link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Cannot insert data: {}", err);
|
eprintln!("Cannot insert a new task: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use crate::{CurrentTaskInfo, Task};
|
use crate::repo::{self, Repository};
|
||||||
|
use crate::CurrentTaskInfo;
|
||||||
|
|
||||||
#[derive(clap::Args)]
|
#[derive(clap::Args)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
|
@ -19,33 +19,32 @@ pub struct Args {
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub args: Args,
|
pub args: Args,
|
||||||
pub current_task_info: Option<CurrentTaskInfo>,
|
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() {
|
if req.current_task_info.is_some() {
|
||||||
panic!("You can edit task only when you don't have an active task, yet");
|
panic!("You can edit task only when you don't have an active task, yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
let idx = req.args.idx;
|
let args = req.args;
|
||||||
if idx == 0 || idx > req.tasks.len() {
|
|
||||||
panic!("invalid index");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut task = &mut req.tasks[idx - 1];
|
let res = repo.update_task(
|
||||||
if let Some(name) = req.args.name {
|
args.idx,
|
||||||
task.name = name;
|
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");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub type TaskId = usize;
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub link: Option<String>,
|
pub link: Option<String>,
|
||||||
|
|
|
@ -55,12 +55,13 @@ fn main() {
|
||||||
cli::add::execute(repo, args);
|
cli::add::execute(repo, args);
|
||||||
}
|
}
|
||||||
cli::SubCommand::Edit(args) => {
|
cli::SubCommand::Edit(args) => {
|
||||||
cli::edit::execute(cli::edit::Request {
|
cli::edit::execute(
|
||||||
|
repo,
|
||||||
|
cli::edit::Request {
|
||||||
args,
|
args,
|
||||||
current_task_info,
|
current_task_info,
|
||||||
tasks,
|
},
|
||||||
tasks_file_path,
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
cli::SubCommand::Remove(args) => {
|
cli::SubCommand::Remove(args) => {
|
||||||
cli::remove::execute(cli::remove::Request {
|
cli::remove::execute(cli::remove::Request {
|
||||||
|
|
11
src/repo.rs
11
src/repo.rs
|
@ -26,8 +26,19 @@ pub struct InsertTaskData {
|
||||||
link: Option<String>,
|
link: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct UpdateTaskData {
|
||||||
|
name: Option<String>,
|
||||||
|
link: Option<Option<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Repository {
|
pub trait Repository {
|
||||||
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error>;
|
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>;
|
fn insert_task(&self, insert_data: InsertTaskData) -> Result<domain::Task, Error>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::domain;
|
use crate::domain;
|
||||||
use crate::repo::{Error, InsertTaskData, Repository};
|
use crate::repo::{Error, InsertTaskData, Repository, UpdateTaskData};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use xdg::BaseDirectories;
|
use xdg::BaseDirectories;
|
||||||
|
@ -41,6 +41,32 @@ impl Repository for FsRepo {
|
||||||
.map(|tasks| tasks.into_iter().map(Task::into).collect())
|
.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> {
|
fn insert_task(&self, insert_data: InsertTaskData) -> Result<domain::Task, Error> {
|
||||||
let new_task = Task {
|
let new_task = Task {
|
||||||
name: insert_data.name,
|
name: insert_data.name,
|
||||||
|
@ -50,13 +76,7 @@ impl Repository for FsRepo {
|
||||||
let mut tasks = self.get_tasks_impl()?;
|
let mut tasks = self.get_tasks_impl()?;
|
||||||
tasks.push(new_task.clone());
|
tasks.push(new_task.clone());
|
||||||
|
|
||||||
let file_path = self
|
self.save_tasks_impl(tasks)?;
|
||||||
.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);
|
|
||||||
|
|
||||||
Ok(new_task.into())
|
Ok(new_task.into())
|
||||||
}
|
}
|
||||||
|
@ -69,4 +89,14 @@ impl FsRepo {
|
||||||
.map_err(|_| Error::NotFound)
|
.map_err(|_| Error::NotFound)
|
||||||
.and_then(|file| serde_json::from_reader(file).map_err(|_| Error::InvalidData))
|
.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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue