use chrono::Local; use clap::Parser; use home::home_dir; use rusqlite::{Connection, Result}; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { /// Create a new note: --create "Hello World" #[arg(short, long, default_value_t = String::new())] create: String, /// Show the latest entries #[arg(short, long, default_value_t = false)] show: bool, /// Show all entries #[arg(long, default_value_t = false)] showall: bool, /// Append or show entries with tag #[arg(short, long, default_value_t = String::new())] tag: String, } struct Note { content: String, date: String, tag: String, } fn main() { let args = Args::parse(); match init_db() { Ok(_) => println!(), Err(e) => println!("Failed to initialize DB: {}", e), }; if args.show { match show_notes(false, &args.tag) { Ok(_) => println!(), Err(e) => println!("Failed to show DB: {}", e), } } if args.create != String::new() { match create_note(&args.create, &args.tag) { Ok(_) => println!(), Err(e) => println!("Failed to throw into DB: {}", e), } } if args.showall { match show_notes(true, &args.tag) { Ok(_) => println!(), Err(e) => println!("Failed to show DB: {}", e), } } if args.tag != String::new() && args.create == String::new() { match show_notes(true, &args.tag) { Ok(_) => println!(), Err(e) => println!("Failed to show DB: {}", e), } } } fn init_db() -> Result<()> { let home = home_dir().unwrap().join(".snotes.db"); let connection = Connection::open(home)?; let query_table = " CREATE TABLE IF NOT EXISTS notes ( nid INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, date TEXT NOT NULL, tag TEXT ); "; match connection.execute(query_table, []) { Ok(v) => println!("INIT OK {}", v), Err(e) => println!("INIT ERR {}", e), }; Ok(()) } fn create_note(content: &String, tag: &String) -> Result<()> { let home = home_dir().unwrap().join(".snotes.db"); let connection = Connection::open(home)?; let date = Local::now(); let date_string = date.format("%m-%d-%y %H:%M").to_string(); let tag_string = if tag.to_string() == String::new() { String::from("quick") } else { tag.to_string() }; let query_insert = "INSERT INTO notes (content, date, tag) VALUES (?1, ?2, ?3)"; match connection.execute(query_insert, [&content, &date_string, &tag_string]) { Ok(v) => println!("CREATE OK {}", v), Err(e) => println!("CREATE ERR {}", e), }; Ok(()) } fn show_notes(all: bool, tag: &String) -> Result<()> { let home = home_dir().unwrap().join(".snotes.db"); let connection = Connection::open(home)?; let mut query = String::from("SELECT * FROM notes LIMIT 10"); if all { query = String::from("SELECT * FROM notes"); } if tag != &String::new() { query = format!("SELECT * FROM notes WHERE tag IS '{}'", tag); } let mut prepare = connection.prepare(&query)?; let notes = prepare.query_map([], |row| { Ok(Note { content: row.get(1)?, date: row.get(2)?, tag: row.get(3)?, }) })?; for note in notes { let unwrapped = note.unwrap(); println!( "{0} #{2}: {1}", &unwrapped.date, &unwrapped.content, &unwrapped.tag ); } Ok(()) }