From ea210ceba08c6816602bc2fdc7c4611532f91e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ernesto=20Gra=C3=B1a?= <55862776+joaco05@users.noreply.github.com> Date: Tue, 12 Aug 2025 19:05:45 -0300 Subject: [PATCH 1/4] Ejercicios del 1-3 resueltos --- Cargo.lock | 89 ++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + hola.json | 6 +++ src/main.rs | 134 ++++++++++++++++++++++++++++++++++------------------ 4 files changed, 185 insertions(+), 46 deletions(-) create mode 100644 hola.json 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/hola.json b/hola.json new file mode 100644 index 0000000..29d8d55 --- /dev/null +++ b/hola.json @@ -0,0 +1,6 @@ +[ + { + "descripcion": "hola", + "completada": true + } +] \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9ec9a9f..407964c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,9 @@ -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)] struct Tarea { descripcion: String, completada: bool, @@ -8,80 +12,118 @@ struct Tarea { impl Tarea { fn mostrar(&self, id: usize) { let estado = if self.completada { "[X]" } else { "[ ]" }; - println!("{} {}: {}",estado, id, self.descripcion); + println!("{} {}: {}", estado, id, self.descripcion); } } fn main() { println!("Bienvenido al gestor de tareas"); - - let mut tareas: Vec = Vec::new(); + let nombre_archivo = "hola.json"; + let mut tareas = cargar_tareas(nombre_archivo).unwrap(); loop { - println!("\ningresa un comando('agregar ', 'listar','salir')"); - + println!( + "\ningresa un comando('agregar ', 'completar ', 'listar','salir')" + ); 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, + }); + println!("\nTarea agregada: {descripcion}"); + } else { + println!("\nLa descripción de la tarea no puede estar vacía."); + } + } + _ 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 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."); - } + _ => 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:"); - + for (i, tarea) in lista_de_tareas.iter().enumerate() { tarea.mostrar(i + 1); } } -/* +fn cargar_tareas + Copy>( + direccion: P, +) -> Result, Box> { + let archivo = File::open(direccion); + let mut tareas: Vec = vec![]; + match archivo { + // Si el archivo no existe lo creo y si existe devuelvo las tareas + Ok(archivo) => { + let reader = BufReader::new(archivo); + tareas = serde_json::from_reader(reader)?; + } + Err(_) => { + File::create(direccion)?; + } + } + 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 (TODO) + + Desafio seis: + etiquetas (TODO) - */ \ No newline at end of file + Desafio siete: + subtareas (TODO) +*/ From 6682a1268e3c4ef2ec6fc49606194195bc21e928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ernesto=20Gra=C3=B1a?= <55862776+joaco05@users.noreply.github.com> Date: Fri, 15 Aug 2025 17:35:03 -0300 Subject: [PATCH 2/4] agrego prioridades --- hola.json | 3 ++- src/main.rs | 56 +++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/hola.json b/hola.json index 29d8d55..b15a88f 100644 --- a/hola.json +++ b/hola.json @@ -1,6 +1,7 @@ [ { "descripcion": "hola", - "completada": true + "completada": false, + "prioridad": 2 } ] \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 407964c..a0d41b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,23 +7,27 @@ use std::{fs::File, io}; struct Tarea { descripcion: String, completada: bool, + prioridad: u8, } impl Tarea { fn mostrar(&self, id: usize) { let estado = if self.completada { "[X]" } else { "[ ]" }; - println!("{} {}: {}", estado, id, self.descripcion); + println!( + "{} {}: {} | prioridad {}", + estado, id, self.descripcion, self.prioridad + ); } } fn main() { println!("Bienvenido al gestor de tareas"); let nombre_archivo = "hola.json"; - let mut tareas = cargar_tareas(nombre_archivo).unwrap(); + let mut tareas = cargar_tareas(nombre_archivo).unwrap_or_default(); loop { println!( - "\ningresa un comando('agregar ', 'completar ', 'listar','salir')" + "\ningresa un comando('agregar ', 'completar ', 'listar','salir', 'prioridad ')" ); let mut entrada = String::new(); io::stdin() @@ -46,6 +50,7 @@ fn main() { tareas.push(Tarea { descripcion: descripcion.to_string(), completada: false, + prioridad: 3, }); println!("\nTarea agregada: {descripcion}"); } else { @@ -67,6 +72,34 @@ fn main() { 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."); + } + } _ => println!("\nComando no reconocido. Intenta de nuevo."), } @@ -84,17 +117,12 @@ fn listar_tareas(lista_de_tareas: &[Tarea]) { fn cargar_tareas + Copy>( direccion: P, ) -> Result, Box> { - let archivo = File::open(direccion); + let archivo_abierto = File::open(direccion); let mut tareas: Vec = vec![]; - match archivo { - // Si el archivo no existe lo creo y si existe devuelvo las tareas - Ok(archivo) => { - let reader = BufReader::new(archivo); - tareas = serde_json::from_reader(reader)?; - } - Err(_) => { - File::create(direccion)?; - } + 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) } @@ -119,7 +147,7 @@ fn guardar_tareas>(lista_tareas: Vec, direccion: P) { emitir reportes (TODO) Desafio cinco: - prioridades (TODO) + prioridades (DONE) Desafio seis: etiquetas (TODO) From 29b7889733ca9c677ab131fc12cec88b45ec542f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ernesto=20Gra=C3=B1a?= <55862776+joaco05@users.noreply.github.com> Date: Fri, 15 Aug 2025 18:37:05 -0300 Subject: [PATCH 3/4] Agrego funcion etiquetas --- hola.json | 7 ------- src/main.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 13 deletions(-) delete mode 100644 hola.json diff --git a/hola.json b/hola.json deleted file mode 100644 index b15a88f..0000000 --- a/hola.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "descripcion": "hola", - "completada": false, - "prioridad": 2 - } -] \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a0d41b2..3d7bbdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,31 +3,50 @@ 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 { "[ ]" }; + let etiqueta = match self.etiquetas { + Tags::Cocina => "Cocina", + Tags::Trabajo => "Trabajo", + Tags::Educacion => "Educacion", + Tags::Hobbie => "Hobbie", + Tags::Social => "Social", + Tags::Vacio => "Vacio", + }; println!( - "{} {}: {} | prioridad {}", - estado, id, self.descripcion, self.prioridad + "{} | {} | {} | {} | {}", + estado, id, self.descripcion, self.prioridad, etiqueta ); } } fn main() { println!("Bienvenido al gestor de tareas"); - let nombre_archivo = "hola.json"; + let nombre_archivo = "tareas.json"; let mut tareas = cargar_tareas(nombre_archivo).unwrap_or_default(); loop { println!( - "\ningresa un comando('agregar ', 'completar ', 'listar','salir', 'prioridad ')" + "\ningresa un comando('agregar ', 'completar ', 'listar','salir', 'prioridad ', etiquetar )" ); let mut entrada = String::new(); io::stdin() @@ -51,6 +70,7 @@ fn main() { descripcion: descripcion.to_string(), completada: false, prioridad: 3, + etiquetas: Tags::Vacio, }); println!("\nTarea agregada: {descripcion}"); } else { @@ -100,7 +120,32 @@ fn main() { 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."), } } @@ -108,6 +153,7 @@ fn main() { 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); @@ -150,7 +196,7 @@ fn guardar_tareas>(lista_tareas: Vec, direccion: P) { prioridades (DONE) Desafio seis: - etiquetas (TODO) + etiquetas (DONE) Desafio siete: subtareas (TODO) From 81ea2942653ccaeb6920398488f89ca671a65feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ernesto=20Gra=C3=B1a?= <55862776+joaco05@users.noreply.github.com> Date: Fri, 15 Aug 2025 19:07:03 -0300 Subject: [PATCH 4/4] Remuevo trait inecesario --- src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3d7bbdb..c16c80f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -160,9 +160,7 @@ fn listar_tareas(lista_de_tareas: &[Tarea]) { } } -fn cargar_tareas + Copy>( - direccion: P, -) -> Result, Box> { +fn cargar_tareas>(direccion: P) -> Result, Box> { let archivo_abierto = File::open(direccion); let mut tareas: Vec = vec![]; if let Ok(archivo) = archivo_abierto {