diff --git a/Cargo.lock b/Cargo.lock index 39f6657..b19f5fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,95 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "proc-macro2" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "todo" version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" diff --git a/Cargo.toml b/Cargo.toml index 7a9a28f..cbfe007 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/src/main.rs b/src/main.rs index 9ec9a9f..c16c80f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,87 +1,201 @@ -use std::io; +use serde::{Deserialize, Serialize}; +use std::io::{BufReader, Write}; +use std::path::Path; +use std::{fs::File, io}; +#[derive(Serialize, Deserialize, Debug)] +enum Tags { + Cocina, + Trabajo, + Educacion, + Hobbie, + Social, + Vacio, +} + +#[derive(Serialize, Deserialize, Debug)] struct Tarea { descripcion: String, completada: bool, + prioridad: u8, + etiquetas: Tags, } impl Tarea { fn mostrar(&self, id: usize) { let estado = if self.completada { "[X]" } else { "[ ]" }; - println!("{} {}: {}",estado, id, self.descripcion); + let etiqueta = match self.etiquetas { + Tags::Cocina => "Cocina", + Tags::Trabajo => "Trabajo", + Tags::Educacion => "Educacion", + Tags::Hobbie => "Hobbie", + Tags::Social => "Social", + Tags::Vacio => "Vacio", + }; + println!( + "{} | {} | {} | {} | {}", + estado, id, self.descripcion, self.prioridad, etiqueta + ); } } fn main() { println!("Bienvenido al gestor de tareas"); - - let mut tareas: Vec = Vec::new(); + let nombre_archivo = "tareas.json"; + let mut tareas = cargar_tareas(nombre_archivo).unwrap_or_default(); loop { - println!("\ningresa un comando('agregar ', 'listar','salir')"); - + println!( + "\ningresa un comando('agregar ', 'completar ', 'listar','salir', 'prioridad ', etiquetar )" + ); let mut entrada = String::new(); io::stdin() .read_line(&mut entrada) .expect("Error al leer la entrada"); let entrada = entrada.trim(); - if entrada == "salir" { - println!("\nSaliendo del gestor de tareas"); - break; - } else if entrada.starts_with("agregar ") { - let descripcion = entrada[8..].trim(); - if !descripcion.is_empty() { - tareas.push(Tarea { - descripcion: descripcion.to_string(), - completada: false, - }); - println!("\nTarea agregada: {}", descripcion); - } else { - println!("\nLa descripción de la tarea no puede estar vacía."); + match entrada { + "salir" => { + println!("\nSaliendo del gestor de tareas"); + guardar_tareas(tareas, nombre_archivo); + break; + } + "listar" => { + listar_tareas(&tareas); } - } else if entrada == "listar" { - listar_tareas(&tareas); - } else if entrada.starts_with("completar ") { - let id: usize = match entrada[10..].trim().parse() { - Ok(num) => num, - Err(_) => { - println!("\nID inválido. Debe ser un número."); - continue; + _ if entrada.starts_with("agregar ") => { + let descripcion = entrada[8..].trim(); + if !descripcion.is_empty() { + tareas.push(Tarea { + descripcion: descripcion.to_string(), + completada: false, + prioridad: 3, + etiquetas: Tags::Vacio, + }); + println!("\nTarea agregada: {descripcion}"); + } else { + println!("\nLa descripción de la tarea no puede estar vacía."); } - }; - if id > 0 && id <= tareas.len() { - tareas[id - 1].completada = true; - println!("\nTarea {} marcada como completada.", id); - } else { - println!("\nID de tarea no válido."); } - } else { - println!("\nComando no reconocido. Intenta de nuevo."); + _ if entrada.starts_with("completar ") => { + let id: usize = match entrada[10..].trim().parse() { + Ok(num) => num, + Err(_) => { + println!("\nID inválido. Debe ser un número."); + continue; + } + }; + if id > 0 && id <= tareas.len() { + tareas[id - 1].completada = true; + println!("\nTarea {id} marcada como completada."); + } else { + println!("\nID de tarea no válido."); + } + } + _ if entrada.starts_with("prioridad ") => { + let id: usize = match entrada[10..].trim().parse() { + Ok(num) => num, + Err(_) => { + println!("\nID inválido. Debe ser un número."); + continue; + } + }; + println!("Escoja prioridad (1, 2 o 3)"); + let mut priority = String::new(); + io::stdin() + .read_line(&mut priority) + .expect("Error al leer entrada"); + let priority = priority.trim().parse::(); + let priority_num = match priority { + Ok(num) => num, + Err(_) => { + println!("Error al castear entrada a u8"); + continue; + } + }; + if (priority_num > 0 && priority_num <= 3) && (id > 0 && id <= tareas.len()) { + tareas[id - 1].prioridad = priority_num; + println!("\nTarea {id} ahora tiene una proridad de {priority_num}."); + } else { + println!("\nID de tarea o prioridad no válido."); + } + } + _ if entrada.starts_with("etiquetar ") => { + let id: usize = match entrada[10..].trim().parse() { + Ok(num) => num, + Err(_) => { + println!("\nID inválido. Debe ser un número."); + continue; + } + }; + println!("Escoja etiqueta (Cocina, Trabajo, Educacion, Hobbie, Social, Vacio)"); + let mut etiqueta = String::new(); + io::stdin() + .read_line(&mut etiqueta) + .expect("Error al leer entrada"); + // lowercase para que funcione independientemente de la tipografia + tareas[id - 1].etiquetas = match etiqueta.trim().to_lowercase().as_str() { + "cocina" => Tags::Cocina, + "trabajo" => Tags::Trabajo, + "educacion" => Tags::Educacion, + "hobbie" => Tags::Hobbie, + "social" => Tags::Social, + _ => { + println!("opcion no reconocida usando etiqueta default 'Vacio'"); + Tags::Vacio + } + }; + } + _ => println!("\nComando no reconocido. Intenta de nuevo."), } - } } -fn listar_tareas(lista_de_tareas: &Vec) { +fn listar_tareas(lista_de_tareas: &[Tarea]) { println!("\nLista de Tareas:"); - + println!("completada | id | descripcion | prioridad | etiqueta"); + for (i, tarea) in lista_de_tareas.iter().enumerate() { tarea.mostrar(i + 1); } } -/* +fn cargar_tareas>(direccion: P) -> Result, Box> { + let archivo_abierto = File::open(direccion); + let mut tareas: Vec = vec![]; + if let Ok(archivo) = archivo_abierto { + // Si el archivo existe devuelvo las tareas + let reader = BufReader::new(archivo); + tareas = serde_json::from_reader(reader)?; + } + Ok(tareas) +} + +fn guardar_tareas>(lista_tareas: Vec, direccion: P) { + let mut archivo = File::create(direccion).unwrap(); + let serialized = serde_json::to_string_pretty(&lista_tareas).unwrap(); + archivo.write_all(serialized.as_bytes()).unwrap(); +} + +/* Desafio uno: - Refactorizar el codigo con un match en vez de if, else if, else - + Refactorizar el codigo con un match en vez de if, else if, else (DONE) + Desafio dos: - Guardar las tareas en un archivo + Guardar las tareas en un archivo serializado en formato JSON con el crate serde (DONE) Desafio tres: - Investigar el crate serde y como se usaria para serializar y deserializar las tareas - + Cargar las tareas desde un archivo al iniciar el programa deserializado en formato JSON con el crate serde (DONE) + Desafio cuatro: - Cargar las tareas desde un archivo al iniciar el programa + emitir reportes (TODO) + + Desafio cinco: + prioridades (DONE) + + Desafio seis: + etiquetas (DONE) - */ \ No newline at end of file + Desafio siete: + subtareas (TODO) +*/