Skip to content

Commit b1220e9

Browse files
committed
add Option to command, to tackle no arguments, modularize whole app
1 parent fd797df commit b1220e9

11 files changed

Lines changed: 132 additions & 91 deletions

File tree

data/tasks.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
"completed": false
1313
},
1414
{
15-
"desc": "abcd",
15+
"desc": "abcdef",
1616
"completed": false
1717
},
1818
{
19-
"desc": "abcdef",
19+
"desc": "mod testing",
2020
"completed": false
2121
}
2222
]

src/commands/add.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::models::Task;
2+
use crate::storage::{load_tasks, save_tasks, show_tasks};
3+
4+
pub fn add(desc: String) {
5+
let mut tasks = load_tasks();
6+
tasks.push(Task {
7+
desc,
8+
completed: false,
9+
});
10+
save_tasks(&tasks);
11+
println!("Task added");
12+
show_tasks();
13+
}

src/commands/complete.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use crate::storage::{load_tasks, save_tasks, show_tasks};
2+
3+
pub fn complete(id: usize) {
4+
let mut tasks = load_tasks();
5+
if id == 0 || id > tasks.len() {
6+
println!("Invalid task ID");
7+
show_tasks();
8+
return;
9+
}
10+
let index = id - 1;
11+
tasks[index].completed = true;
12+
save_tasks(&tasks);
13+
show_tasks();
14+
}

src/commands/delete.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use crate::storage::{load_tasks, save_tasks, show_tasks};
2+
3+
pub fn delete(id: usize) {
4+
let mut tasks = load_tasks();
5+
if id == 0 || id > tasks.len() {
6+
println!("Invalid input, nothing was deleted, \nTry Again");
7+
show_tasks();
8+
return;
9+
}
10+
let index = id - 1;
11+
tasks = tasks
12+
.into_iter()
13+
.enumerate()
14+
.filter(|(i, _)| *i != index)
15+
.map(|(_, task)| task)
16+
.collect();
17+
save_tasks(&tasks);
18+
let deleted = &tasks[index].desc;
19+
println!("Deleted {:?} successfully", deleted);
20+
show_tasks();
21+
}

src/commands/list.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use crate::storage::show_tasks;
2+
3+
pub fn list() {
4+
show_tasks();
5+
}

src/commands/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pub mod add;
2+
pub mod complete;
3+
pub mod delete;
4+
pub mod list;
5+
6+
pub use add::add;
7+
pub use complete::complete;
8+
pub use delete::delete;
9+
pub use list::list;

src/main.rs

Lines changed: 20 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,39 @@
1+
mod commands;
2+
mod models;
3+
mod storage;
14

2-
use clap::{Parser, Subcommand};
3-
use serde::{Serialize, Deserialize};
4-
use std::fs::{File, OpenOptions};
5-
use std::io::{BufReader, BufWriter};
6-
use std::path::Path;
5+
use commands::{add, complete, delete, list};
76

8-
const DATA_FILE: &str = "data/tasks.json";
7+
use clap::{Parser, Subcommand};
98

10-
#[derive(Parser)]
9+
#[derive(Parser, Debug)]
1110
#[command(name = "Smart Tasker")]
1211
#[command(about = "CLI to manage tasks")]
1312
#[command(version)]
1413
#[command(author = "Adarsh")]
15-
struct Cli{
14+
struct Cli {
1615
#[command(subcommand)]
17-
command: Commands
16+
command: Option<Commands>,
1817
}
1918

20-
#[derive(Subcommand)]
21-
enum Commands{
19+
#[derive(Subcommand, Debug)]
20+
enum Commands {
2221
Add { desc: String },
2322
List,
24-
Completed { id: usize },
25-
Delete { id: usize }
26-
}
27-
28-
#[derive(Serialize, Deserialize, Debug, Clone)]
29-
struct Task{
30-
desc: String,
31-
completed: bool
23+
Complete { id: usize },
24+
Delete { id: usize },
3225
}
3326

34-
fn main(){
27+
fn main() {
3528
let cli = Cli::parse();
3629

37-
match cli.command{
38-
Commands::Add { desc } => {
39-
let mut tasks = load_tasks();
40-
tasks.push(Task {
41-
desc,
42-
completed: false
43-
});
44-
save_tasks(&tasks);
45-
println!("Task added");
46-
show_tasks();
47-
},
48-
Commands::List => {
49-
show_tasks();
50-
},
51-
Commands::Completed { id } => {
52-
let mut tasks = load_tasks();
53-
if id == 0 || id > tasks.len(){
54-
println!("Invalid task ID");
55-
show_tasks();
56-
return;
57-
}
58-
let index = id - 1;
59-
tasks[index].completed = true;
60-
save_tasks(&tasks);
61-
show_tasks();
62-
},
63-
Commands::Delete { id } => {
64-
let mut tasks = load_tasks();
65-
if id == 0 || id > tasks.len(){
66-
println!("Invalid input, nothing was deleted, \nTry Again");
67-
show_tasks();
68-
return;
69-
}
70-
let index = id - 1;
71-
tasks = tasks.into_iter().enumerate().filter(|(i,_)| *i != index).map(|(_,task)|task).collect();
72-
save_tasks(&tasks);
73-
let deleted = &tasks[index].desc;
74-
println!("Deleted {:?} successfully", deleted);
75-
show_tasks();
30+
match cli.command {
31+
Some(Commands::Add { desc }) => add(desc),
32+
Some(Commands::List) => list(),
33+
Some(Commands::Complete { id }) => complete(id),
34+
Some(Commands::Delete { id }) => delete(id),
35+
None => {
36+
eprintln!("No command given. Use `--help` to see help");
7637
}
7738
}
7839
}
79-
80-
fn load_tasks() -> Vec<Task>{
81-
if !Path::new(DATA_FILE).exists(){
82-
return Vec::new()
83-
}
84-
85-
let file = File::open(DATA_FILE).expect("failed to open DATA_FILE");
86-
let reader = BufReader::new(file);
87-
serde_json::from_reader(reader).unwrap_or_else(|_| Vec::new())
88-
}
89-
90-
fn save_tasks(tasks: &Vec<Task>) {
91-
let file = OpenOptions::new()
92-
.create(true)
93-
.write(true)
94-
.truncate(true)
95-
.open(DATA_FILE)
96-
.expect("failed to write file");
97-
98-
let writer = BufWriter::new(file);
99-
serde_json::to_writer_pretty(writer, tasks).expect("Failed to serialise task");
100-
}
101-
102-
fn show_tasks(){
103-
let tasks = load_tasks();
104-
for (i, task) in tasks.iter().enumerate(){
105-
let status = if task.completed { "[x]" } else { "[ ]"};
106-
println!("{} {} {} ", i+1, status, task.desc);
107-
}
108-
}

src/models/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod task;
2+
pub use task::Task;

src/models/task.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Serialize, Deserialize, Debug, Clone)]
4+
pub struct Task {
5+
pub desc: String,
6+
pub completed: bool,
7+
}

src/storage/file.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::models::Task;
2+
3+
use std::fs::{File, OpenOptions};
4+
use std::io::{BufReader, BufWriter};
5+
use std::path::Path;
6+
7+
const DATA_FILE: &str = "data/tasks.json";
8+
9+
pub fn load_tasks() -> Vec<Task> {
10+
if !Path::new(DATA_FILE).exists() {
11+
return Vec::new();
12+
}
13+
14+
let file = File::open(DATA_FILE).expect("failed to open DATA_FILE");
15+
let reader = BufReader::new(file);
16+
serde_json::from_reader(reader).unwrap_or_else(|_| Vec::new())
17+
}
18+
19+
pub fn save_tasks(tasks: &Vec<Task>) {
20+
let file = OpenOptions::new()
21+
.create(true)
22+
.write(true)
23+
.truncate(true)
24+
.open(DATA_FILE)
25+
.expect("failed to write file");
26+
27+
let writer = BufWriter::new(file);
28+
serde_json::to_writer_pretty(writer, tasks).expect("Failed to serialise task");
29+
}
30+
31+
pub fn show_tasks() {
32+
let tasks = load_tasks();
33+
for (i, task) in tasks.iter().enumerate() {
34+
let status = if task.completed { "[x]" } else { "[ ]" };
35+
println!("{} {} {} ", i + 1, status, task.desc);
36+
}
37+
}

0 commit comments

Comments
 (0)