Appropriate way to update value in dashmap

I'm currently working on a function to parse and recursively parse a vector of strings for keywords, which are stored in a dashmap, where those keywords are also values in that dashmap which also need to be parsed and rebuilt.

here's a snippet from the parser function related to the problem at hand

&self.snippets.get(&(language.into(),snippet_name.to_string())).unwrap().body.iter().for_each(|line| {
 
            ...
                            assembled_snippet.append(&mut self.chamber_snippet(language.into(),sub_snippet_name,tabstop_count,snippet_args));
                    ...
            
        ...
        });
the error I'm getting:
closure requires unique access to `self` but it is already borrowed

the messages with relative locations:

at start of clozure:

rifle.rs(94, 10): borrow occurs here

location of internal borrow:

 second borrow occurs due to use of `self` in closure

located at start of clozure:

 a temporary with access to the first borrow is created here ...

end_of_clozure:

... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type dashmap...

I've managed to fix this by cloning the body and calling an iterator on the clone like so:

let body_to_parse=self.snippets.get(&(language.into(),snippet_name.to_string())).unwrap().body.clone();
body_to_parse.iter().for_each(|line| {

however, I'd rather avoid creating a copy of the data (if at all possible). is there a way to operate on the existing data that's part while recursively grabbing and operating on data that is part of the same data structure without copying the data first?

off topic but does cloning take linear time?

Please post full errors as reported by cargo build.

here's the full output (warnings omitted)

   Compiling sniper-core v0.1.0 (/home/skewballfox/Workspace/sniper/sniper/sniper)

error[E0500]: closure requires unique access to `self` but it is already borrowed
   --> sniper/src/rifle.rs:95:110
    |
95  |         self.snippets.get(&(language.into(),snippet_name.to_string())).unwrap().body.clone().iter().for_each(|line| {
    |         -----------------------------------------------------------------------                              ^^^^^^ closure construction occurs here
    |         |
    |         borrow occurs here
    |         a temporary with access to the first borrow is created here ...
...
141 |                         if self.snippets.contains_key(&(language.into(),sub_snippet_name.to_string())){
    |                            ---- second borrow occurs due to use of `self` in closure
...
176 |         });//no more lines
    |           - ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `dashmap::mapref::one::Ref<'_, (std::string::String, std::string::String), Snippet>`

error: aborting due to previous error; 5 warnings emitted

For more information about this error, try `rustc --explain E0500`.
error: could not compile `sniper-core`

the full function can be found here

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.