How to edit rust with function

Currently I am trying to create a crud system in Rust, but stuck on how to update the current todo item with new value.

    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 _getitem = std::env::args().nth(3).expect("Please provide an item");

    struct Todo {
        map: HashMap<String, bool>,
    }

   if action == "edit" {
        match todo.edit(&item, &_getitem) {
            None => println!("'{}' is not present in the list", item),
            Some(_) => match todo.save() {
                Ok(_) => println!("todo saved"),
                Err(why) => println!("An error occurred: {}", why),
            },
        }
    }

    fn edit(&mut self, key: &String, value: &String) -> Option<()> {
        let elements = self.map.get_mut(key);
        elements.push(value.to_string());
    }
/// db.json looks like (hash map)
{
  "bob": true,
  "new": true
}
  1. You probably want to do a pub enum Action { Edit, ... }

  2. What is the error you are running into ? / What is failing ? Are you looking for self.map.insert(key.clone(), value.clone()) ?

I want to replace the selected value, so first it should find the value in the json file and then update it with the new value.

I don't get it.

  1. All you have is a HashMap, a key, and a value. What can you do besides HashMap in std::collections - Rust ?

  2. Why is the HashMap (string, bool) while the key & value are both string ?

Where does json come in with all this ?

Check the updated snippet, basically I want to replace for instance "bob" string in db.json with new item.

From your provided snippet, there's not much we can say to help you out. Please provide the full snippet and preferably a link to a working example in https://play.rust-lang.org/

I do not understand if the problem is:

  1. help me with high level design (answer: I do not know what you are trying to do)

  2. help me fix this compile error (answer: you are trying to insert a (String, String) into a hashmap that is (String, bool))

A few things from your provided gist:

struct Todo {
  map: HashMap<String, bool>,
}

Here you are indicating that the map inside of the Todo struct has String as keys and bool as values. To explain this in JSON terms, we are talking about an object like this:

{
  "buy dinner": true,
  "take the dog out": false,
  "do the laundry": true
}

Because of this, your code in the complete function compiles:

fn complete(&mut self, key: &String) -> Option<()> {
  match self.map.get_mut(key) {
    Some(v) => Some(*v = !*v),
    None => None,
  }
}

But the code for the edit function does not:

fn edit(&mut self, key: &String, value: String) -> Option<String> {
  self.map.insert(key.to_string(), value);
}

The first issue here is that you are expecting a key to be a reference to a String, and value to be a String; but your HashMap expects values of type bool as mentioned before.

The second issue has to do with the return type (which I guess you'll intuitively know how to fix, but I'll explain it anyway for other users' reference). The insert function from the HashMap returns an Option of the HashMap's value type, bool in this case, so the return type for the edit function should be Option<bool>.

The third issue is that you placed a semicolon at the end of the line where you insert the value:

self.map.insert(key.to_string(), value); // <--- Here's a semicolon at the end

In Rust, when a semicolon is found at the end of a function means that the return type will be the unit type (()). As a rule of thumb, never put a semicolon at the end of a function, unless you explicitly want to return a unit.

The third issue is that the edit function expects an owned String as its second argument, but you are passing it a reference to a String (&String), exactly as you are doing with its first argument):

} else if action == "edit" {
        match todo.edit(&item, &_getitem) {

I hope this is clear enough for you and allows you to continue coding.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.