Created
February 14, 2017 07:39
-
-
Save BrainMaestro/f08e38c561e71e7dc10172c64586fc8b to your computer and use it in GitHub Desktop.
Terminal todo application in Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{fmt, io}; | |
struct TodoItem { | |
id: usize, | |
title: String, | |
completed: bool, | |
deleted: bool, | |
} | |
struct TodoList { | |
items: Vec<TodoItem> | |
} | |
enum Operation { | |
Complete, | |
Toggle, | |
Delete, | |
} | |
impl TodoItem { | |
fn new(id: usize, title: &str) -> Self { | |
TodoItem { | |
id: id, | |
title: title.to_string(), | |
completed: false, | |
deleted: false, | |
} | |
} | |
fn toggle(&mut self, done: Option<bool>) { | |
match done { | |
None => self.completed = !self.completed, | |
Some(done) => self.completed = done, | |
} | |
} | |
fn delete(&mut self) { | |
self.deleted = true; | |
} | |
} | |
impl TodoList { | |
fn new() -> Self { | |
TodoList { items: Vec::<TodoItem>::new() } | |
} | |
fn add_item(&mut self, title: &str) { | |
let len = self.items.len() + 1; | |
if title != "" { self.items.push(TodoItem::new(len, title)) } | |
} | |
fn find_item(&mut self, index: Option<usize>, title: Option<&str>, operation: &Operation) { | |
let todo = if let Some(id) = index { | |
self.items.iter_mut().find(|ref item| item.id == id) | |
} else if let Some(title) = title { | |
self.items.iter_mut().find(|ref item| item.title == title) | |
} else { | |
None | |
}; | |
if let Some(todo) = todo { | |
match *operation { | |
Operation::Complete => todo.toggle(Some(true)), | |
Operation::Toggle => todo.toggle(None), | |
Operation::Delete => todo.delete(), | |
} | |
} | |
} | |
} | |
impl fmt::Display for TodoItem { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
let done = if self.completed { "✔" } else { " " }; | |
write!(f, "[{}] - {}. {}", done, self.id, self.title) | |
} | |
} | |
impl fmt::Display for TodoList { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
let mut output = String::new(); | |
for item in &self.items { | |
if !item.deleted { output.push_str(&format!("{}\n", item)) } | |
} | |
write!(f, "{}", output) | |
} | |
} | |
fn main() { | |
let mut todo_list = TodoList::new(); | |
println!("Todo List\n========="); | |
loop { | |
let mut command = String::new(); | |
println!("{}", todo_list); | |
io::stdin() | |
.read_line(&mut command) | |
.expect("failed to read line"); | |
let input: Vec<&str> = command.split_whitespace().collect(); | |
let command = input[0]; | |
let todo_string = input[1..].join(" "); | |
let todos: Vec<&str> = todo_string.split(|c| c == ';' || c == ',').collect(); | |
match command { | |
"a" | "-a" | "add" | "--add" => for todo in todos { todo_list.add_item(todo.trim()); }, | |
"c" | "-c" | "complete" | "--complete" => find_all(&mut todo_list, todos, Operation::Complete), | |
"t" | "-t" | "toggle" | "--toggle" => find_all(&mut todo_list, todos, Operation::Toggle), | |
"d" | "-d" | "delete" | "--delete" => find_all(&mut todo_list, todos, Operation::Delete), | |
"h" | "-h" | "help" | "--help" => print_help(), | |
"exit" | "q" | "quit" => break, | |
_ => println!("Invalid command: `{}`\nType 'h' or 'help' for help", command), | |
} | |
} | |
} | |
fn find_all(todo_list: &mut TodoList, todos: Vec<&str>, operation: Operation) { | |
for todo in todos { | |
let todo_string = todo.trim(); | |
let (index, title) = match todo_string.parse::<usize>() { | |
Ok(index) if index <= todo_list.items.len() => (Some(index), None), | |
Ok(_) | Err(_) if todo_string != "" => (None, Some(todo_string)), | |
_ => (None, None) | |
}; | |
todo_list.find_item(index, title, &operation); | |
} | |
} | |
fn print_help() { | |
println!("Usage: [options] [, separated list of arguments]"); | |
println!("a, add \t\t\t Add new todo items"); | |
println!("c, complete \t\t Complete todo items"); | |
println!("t, toggle \t\t Toggle todo items"); | |
println!("d, delete \t\t Delete todo items"); | |
println!("============================================"); | |
println!("h, help \t\t Help"); | |
println!("q, quit \t\t Quit"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment