1

Is there a way to borrow as mutable all the way down the chain and return ownership to config? The memory operations here seem really excessive to update a single variable.

The code is working as expected but coming from high level languages it seems a little "hacky". Am I on the right track? The documentation is a little sparse on this library.

// Read Config File let mut file = File::open("config.yaml").unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents); // Get Mutable 'endpoints' let mut docs = YamlLoader::load_from_str(&contents).unwrap(); let mut config = docs[0].as_hash().unwrap().clone(); let mut endpoints = config[&Yaml::from_str("endpoints")].as_vec().unwrap().clone(); // Find the correct 'endpoint' for (i, endpoint) in endpoints.clone().iter().enumerate() { let mut endpoint = endpoint.as_hash().unwrap().clone(); if endpoint[&Yaml::from_str("name")] == Yaml::from_str("Current Name") { // Found the endpoint, let's update it's name endpoint.insert(Yaml::from_str("name"), Yaml::from_str("New Name")); endpoints.insert(i, Yaml::Hash(endpoint)); config.insert(Yaml::from_str("endpoints"), Yaml::Array(endpoints.clone())); } } 
5
  • Not sure at all, but I would try using as_mut on the options I guess. Doubtful it'll work the whole way though. Commented Jul 22, 2021 at 18:06
  • Thanks for the tip, and I did try using as_mut. However i kept running into this error: temporary value dropped while borrowed, consider using a 'let' binding to create a longer lived value This does not work: docs[0].as_hash().as_mut().unwrap(); Am I using as_mut incorrectly? I think unwrap may be to blame here? Commented Jul 22, 2021 at 18:52
  • unwrap would be causing the errors. But I'm not sure what to do here... The other possibilty would be to use an if let or a match to take out the values? Commented Jul 22, 2021 at 19:03
  • after playing around a bit more. It seems 'as_hash' always returns an immutable borrow. The library also exposes into_hash(), but it looks like this attempts to move it. Commented Jul 22, 2021 at 19:15
  • Thanks for pointing me in the direction of match. Using this in combination with borrow_mut seems to be doing exactly what I was looking for. From what I can tell this should avoid duplicating any data in memory now correct? Commented Jul 22, 2021 at 20:13

1 Answer 1

1

This is working, and I think solves all the pitfalls of my previous code.

let mut docs = YamlLoader::load_from_str(&contents).unwrap(); let mut config = docs[0].borrow_mut(); if let Yaml::Hash(hash_map) = config { if let Yaml::Array(endpoints) = hash_map[&Yaml::from_str("endpoints")].borrow_mut() { for endpoint in endpoints.iter_mut() { if let Yaml::Hash(endpoint) = endpoint.borrow_mut() { if endpoint[&Yaml::from_str("name")] == Yaml::from_str("Current Name") { endpoint.insert(Yaml::from_str("name"), Yaml::from_str("New Name")); } } } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.