Skip to content

Scoped access to inner HashMap<String, String> #1

@nwtnni

Description

@nwtnni

Hello!

I'm running into a problem trying to collect some key-value pairs from the MDC HashMap due to conflicting lifetimes. Here's a Rust playground link to the following example, which fails to compile:

use std::collections::HashSet;

fn main() {

    let mut keys = HashSet::new();
    keys.insert("key-a");
    keys.insert("key-b");

    let mut entries = Vec::new();
    for key in &keys {
        if let Some(value) = log_mdc::get(*key, |value| value) {
            entries.push((key, value));
        }
    }
    
    println!("{:?}", entries);

}

The problem is that value is not allowed to escape the closure. So as far as I can tell there's currently no way to access multiple values without allocating--I could call value.into_owned(), but I'd prefer not to if possible. One way to solve this problem would be to allow access to the entire HashMap<String, String> inside a user-provided closure, instead of one value at at time:

//! log_mdc/src/lib.rs

fn with<F, T>(apply: F) -> T
    where F: FnOnce(&HashMap<String, String>) -> T
{
  MDC.with(|mdc| apply(mdc.borrow()))
}
use std::collections::HashSet;

fn main() {
    let mut keys = HashSet::new();
    keys.insert("key-a");
    keys.insert("key-b");

    log_mdc::with(|mdc| {
      let mut entries = Vec::new();
      for key in &keys {
          if let Some(value) = mdc.get(key) {
              entries.push((key, value));
          }
      }
      println!("{:?}", entries);
  });
}

This does expose more implementation details than before, but otherwise looks backward-compatible to me. Does adding the with function sound reasonable? If so, I can open a PR!

Thanks,
Newton

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions