I am attempting to create a cache of user ids to usernames, stored in a HashMap which starts empty. As requests are made to lookup the username in this HashMap cache if it doesn't exist it gets fetched from the credentials store (in our case, pgs_files lookup to /etc/passwd but removed from this code for clarity) and stored in the cache for the next time. I am trying to update the HashMap from a self reference, and the borrow checker has berated me into submission. I have tried changing around muts, selfs and passing copies, but keep bumping into errors.
src/main.rs:15:25: 15:36 error: cannot borrow `self.mapper` as mutable because it is also borrowed as immutable [E0502]
src/main.rs:15 self.mapper.insert(key.to_owned(), name.to_owned());
I would be grateful for any information on where I am going wrong in the code below.
Thank you!
use std::collections::HashMap;
type UidGidHashMap = HashMap<u32, String>;
struct UidGidHash { mapper: UidGidHashMap }
impl UidGidHash {
fn search(&mut self, key: u32) -> String {
let username: String = match self.mapper.get(&key) {
Some(username) => username.to_string(),
None => {
let name = lookup_user(key);
self.mapper.insert(key.to_owned(), name.to_owned());
return name
}
};
username.to_owned()
}
}
fn main() {
// Gets "Jenny" - a direct lookup is working fine
let mut uid = 503;
let myuser = lookup_user(uid);
println!("{:?}", myuser);
// Create struct with hashmap of uids->usernames
let mut table = UidGidHash { mapper: UidGidHashMap::new() };
// Look for Jenny in the cache. As it is empty, insert the K:V pair, getting V from lookup_user(uid: u32)
uid = 503;
let mut user = table.search(uid);
println!("User is {:?}", user);
}
fn lookup_user(uid: u32) -> String {
let user = match uid {
0 => "root",
502 => "Matt",
503 => "Jenny",
_ => "UNKNOWN!"
};
user.to_string()
}