Fallible map Entry .or_insert_with()

⚓ Rust    📅 2026-03-03    👤 surdeus    👁️ 1      

surdeus

Hi, 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(())
}

(Playground)

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

Read full topic

🏷️ Rust_feed