How to map an Option to a String for formatting while providing an &'static str as a default?

Viewed 203

I have a function that returns an Option<> result. I would like to print it with a fallback like this:

println!("Result: {}", result.map_or("not found", |r| r.to_string()));

Unfortunately, this way I either:

  • get a &'static str vs String type error,
  • or get a "does not live long enough" if I do &r.to_string(),
  • or have to convert "not found" to a String which is ugly and seems very unnecessary.

Is there a way to do this conversion while keeping the default value an &'static str?

2 Answers

With a combination of Option::as_ref and map_or, the trick is to borrow the owned Option<String> with as_ref:

println!(
    "Result: {}",
    result.as_ref().map_or("not found", String::as_str)
);

Playground

As per the comments, in case is a generic type, use map to transform it to a String first (allocating it), then same process as above:

result
    .map(|f| foo_to_string(&f))
    .as_ref()
    .map_or("not found", String::as_str)

Playground

I not sure to understand well. You want do this?

fn main()
{
    let resutl: Option<&'static str> = Some("test 1");
    println!("{:?}", resutl.map_or("8".into(), |r| r));
    
    let resutl: Option<String> = Some(String::from("test 2"));
    println!("{:?}", resutl.map_or("8".into(), |r| r));
    
    let resutl: Option<&str> = Some("test 3");
    println!("{:?}", resutl.map_or("8".into(), |r| r));   
}
Related