Fallible map Entry .or_insert_with()
⚓ Rust 📅 2026-03-03 👤 surdeus 👁️ 1Hi, is there some method for .entry(k).or_insert_with_key(fallible_func_returns_result) ?
use anyhow::Result;
use std::collections::hash_map::{Entry, HashMap};
use std::fmt::Debug;
// This is just an example of a fallible function
fn listing<S>(path: S) -> Result<String>
where
S: AsRef<str> + Debug,
{
eprintln!("Not cached, requesting listing from filesystem ({path:?})");
let ls = std::process::Command::new("ls")
.arg(path.as_ref())
.output()?;
Ok(String::from_utf8(ls.stdout)?)
}
fn main() -> Result<()> {
let mut ls: HashMap<&'static str, String> = HashMap::new();
// error: expected `listing` to return `String`, but it returns `Result<String, Error>`
// let a = ls.entry("/").or_insert_with_key(listing);
// let b = ls.entry("/").or_insert_with_key(listing);
// But this is ugly... is there something better?
let key = "/";
let binding = match ls.entry(key) {
Entry::Occupied(e) => e,
Entry::Vacant(e) => e.insert_entry(listing(key)?),
};
let a = binding.get(); // Must be a separate statement
println!("Listing for {key}:\n{}", a);
let key = "/";
let binding = match ls.entry(key) {
Entry::Occupied(e) => e,
Entry::Vacant(e) => e.insert_entry(listing(key)?),
};
let b = binding.get(); // Must be a separate statement
println!("Listing for {key}:\n{}", b);
// I would like to have something like:
// let a = ls.entry("/").or_try_insert_with_key(listing)?;
Ok(())
}
Output:
Listing for /:
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
playground
proc
root
run
sbin
srv
sys
tmp
usr
var
Listing for /:
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
playground
proc
root
run
sbin
srv
sys
tmp
usr
var
Errors:
Compiling playground v0.0.1 (/playground)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.63s
Running `target/debug/playground`
Not cached, requesting listing from filesystem ("/")
2 posts - 2 participants
🏷️ Rust_feed