Last active
March 4, 2024 19:12
-
-
Save Marmiz/541c3ccea832a27bfb60d4882450a4a8 to your computer and use it in GitHub Desktop.
Final section of todo-cli
This file contains hidden or 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::collections::HashMap; | |
fn main() { | |
let action = std::env::args().nth(1).expect("Please provide an action"); | |
let item = std::env::args().nth(2).expect("Please provide an item"); | |
let mut todo = Todo::new().expect("Initialisation of db failed"); | |
if action == "add" { | |
todo.insert(item); | |
match todo.save() { | |
Ok(_) => println!("todo saved"), | |
Err(why) => println!("An error occurred: {}", why), | |
} | |
} else if action == "complete" { | |
match todo.complete(&item) { | |
None => println!("'{}' is not present in the list", item), | |
Some(_) => match todo.save() { | |
Ok(_) => println!("todo saved"), | |
Err(why) => println!("An error occurred: {}", why), | |
}, | |
} | |
} | |
} | |
struct Todo { | |
// use rust built in HashMap to store key - val pairs | |
map: HashMap<String, bool>, | |
} | |
impl Todo { | |
fn new() -> Result<Todo, std::io::Error> { | |
let f = std::fs::OpenOptions::new() | |
.write(true) | |
.create(true) | |
.read(true) | |
.open("db.json")?; | |
match serde_json::from_reader(f) { | |
Ok(map) => Ok(Todo { map }), | |
Err(e) if e.is_eof() => Ok(Todo { | |
map: HashMap::new(), | |
}), | |
Err(e) => panic!("An error occurred: {}", e), | |
} | |
} | |
fn insert(&mut self, key: String) { | |
// insert a new item into our map. | |
// active state is set to true by default. | |
self.map.insert(key, true); | |
} | |
fn save(self) -> Result<(), Box<dyn std::error::Error>> { | |
let f = std::fs::OpenOptions::new() | |
.write(true) | |
.create(true) | |
.truncate(true) | |
.open("db.json")?; | |
serde_json::to_writer_pretty(f, &self.map)?; | |
Ok(()) | |
} | |
fn complete(&mut self, key: &String) -> Option<()> { | |
match self.map.get_mut(key) { | |
Some(v) => Some(*v = false), | |
None => None, | |
} | |
} | |
} |
Thanks for raising this.
This is a case where writing some test would have helped me catching this in time :)
Anyway the fix is quite easy: it's enough to set truncate
OpenOption to true
when opening the file:
fn save(self) -> Result<(), Box<dyn std::error::Error>> {
let f = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true) // add this flag
.open("db.json")?;
serde_json::to_writer_pretty(f, &self.map)?;
Ok(())
}
Docs about truncate.
Happy coding 👍
Not seeing any data written to db.json, it was working before adding serde_json
Hey @bscott, just tried and seems to be working on my end.
Can you provide any additional info that can help me understand better the issue? Like versions...etc
Thanks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, thanks for a nice tutorial, I've got a bug.
Repro:
and the json will be broken: