diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8101bfe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.fontSize": 18 +} \ No newline at end of file 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..9656a96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,10 @@ use std::io; +use std::fs::{File, OpenOptions}; +use std::io::{Read, Write, ErrorKind}; +use serde::{Deserialize, Serialize}; +use serde_json; +#[derive(Serialize, Deserialize, Debug)] struct Tarea { descripcion: String, completada: bool, @@ -15,10 +20,14 @@ impl Tarea { fn main() { println!("Bienvenido al gestor de tareas"); - let mut tareas: Vec = Vec::new(); + let archivo_de_tareas = "task-list.json"; + + // Load tasks + let mut tareas = load_task_list(archivo_de_tareas); + // let mut tareas: Vec = Vec::new(); loop { - println!("\ningresa un comando('agregar ', 'listar','salir')"); + println!("\ningresa un comando('agregar ', 'completar ', 'listar', 'salir')"); let mut entrada = String::new(); io::stdin() @@ -26,10 +35,50 @@ fn main() { .expect("Error al leer la entrada"); let entrada = entrada.trim(); - if entrada == "salir" { + // 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."); + // } + // } 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 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."); + // } + + match entrada { + "salir" => { println!("\nSaliendo del gestor de tareas"); + save_task_list(archivo_de_tareas, &tareas); break; - } else if entrada.starts_with("agregar ") { + } + "listar" => { + listar_tareas(&tareas); + } + s if s.starts_with("agregar ") => { let descripcion = entrada[8..].trim(); if !descripcion.is_empty() { tareas.push(Tarea { @@ -40,10 +89,9 @@ fn main() { } else { println!("\nLa descripción de la tarea no puede estar vacía."); } - } else if entrada == "listar" { - listar_tareas(&tareas); - } else if entrada.starts_with("completar ") { - let id: usize = match entrada[10..].trim().parse() { + } + s if s.starts_with("completar ") => { + let id: usize = match entrada[10..].trim().parse() { Ok(num) => num, Err(_) => { println!("\nID inválido. Debe ser un número."); @@ -56,9 +104,11 @@ fn main() { } else { println!("\nID de tarea no válido."); } - } else { - println!("\nComando no reconocido. Intenta de nuevo."); } + _ => { + println!("Unknown command"); + } + } } } @@ -71,6 +121,51 @@ fn listar_tareas(lista_de_tareas: &Vec) { } } +fn load_task_list(path: &str) -> Vec { + let file = File::open(path); + + + let mut task_file = match file { + Ok(file) => file, + Err(error) => match error.kind() { + ErrorKind::NotFound => match File::create(path) { + Ok(fc) => fc, + Err(e) => panic!("Problem creating the file: {e:?}"), + }, + _ => { + panic!("Problem opening the file: {error:?}"); + } + }, + }; + + let mut contents = String::new(); + task_file.read_to_string(&mut contents).expect("Failed to read task list file"); + + if contents.trim().is_empty() { + // New file or empty, start with empty vector + Vec::new() + } else { + serde_json::from_str(&contents).unwrap_or_else(|err| { + eprintln!("Error parsing JSON: {}. Starting with empty list.", err); + Vec::new() + }) + } +} + +fn save_task_list(path: &str, tasks: &Vec) { + let json = serde_json::to_string_pretty(tasks).expect("Failed to serialize tasks"); + let mut file = OpenOptions::new() + .write(true) + .truncate(true) + .open(path) + .expect("Failed to open task list file for writing"); + + file.write_all(json.as_bytes()).expect("Failed to write task list file"); +} + + + + /* Desafio uno: Refactorizar el codigo con un match en vez de if, else if, else diff --git a/task-list.json b/task-list.json new file mode 100644 index 0000000..01d2a9e --- /dev/null +++ b/task-list.json @@ -0,0 +1,10 @@ +[ + { + "descripcion": "tareaOne", + "completada": false + }, + { + "descripcion": "TareaTwo", + "completada": true + } +] \ No newline at end of file