I am working on some code that looks like this:
fn my_operation() -> Result<()> {
let mut map = BTreeMap::new();
let object = serde_json::from_str(/*some str*/)?;
for (key, value) in object {
let &mut entry = map.entry(key);
process_value(value, &mut entry);
}
fn process_value(value: Value, entry: &mut Entry<String, Vec<usize>>) {
match value {
Value::String(s) => {
// conditionally insert into the map, nothing may be added, so no entry is created in this case
if s.len() > 10 {
entry.or_default().push(s.len());
}
}
Value::Array(a) => a.into_iter().for_each(|item| process_value(item, entry),
_ => todo!()
}
The issue is that insert
on VacantEntry
consumes self
so I am not able to reuse the entry once I have inserted in it once.
I have considered passing the key and the map to the process_value
function. This would means performing a lookup every time, and cloning the key every time I need to insert. I also tought about passing a Either<Entry<String, Vec<usize>>, &mut Vec<usize>>
but that's rather ugly.
I am wondering if it would be possible for the Entry::insert_*
method to mutate in place the Entry
and turn a VavantEntry
into a OccupiedEntry
, and thus only mutably borrowing self
, or for VacantEntry
to expose a method that returns an OccupiedEntry
upon insert?