Matching `Option<String>`?

The following code doesn’t work because the .map() closure returns a temporary value:

let card_store = match card_store_path
    .extension()
    .map(|oss| oss.to_string_lossy().to_lowercase().as_str())
{
    Some("md") => read_card_store_from_md_file(card_store_path)?,
    _ => read_card_store_from_tsv(card_store_path)?,
};

However, I can’t seem to match against String values in patterns – which would allow me to remove .as_str(). Is there a way to do this? I’d like to avoid unwrapping the option via if let.

String implements Deref<Target = str> so you can do

let card_store = match card_store_path
    .extension()
    .map(|oss| oss.to_string_lossy().to_lowercase())
    .as_deref()
{
    Some("md") => read_card_store_from_md_file(card_store_path)?,
    _ => read_card_store_from_tsv(card_store_path)?,
};

For similar cases where Deref isn't implemented you can do something like

        .as_ref()
        .map(|oss| oss.as_str())
1 Like

Another similar solution is something like:

let card_store = match card_store_path
    .extension()
    .and_then(|s| s.to_str())
{
    Some(ext) if ext.eq_ignore_ascii_case("md") => read_card_store_from_md_file(card_store_path)?,
    _ => read_card_store_from_tsv(card_store_path)?,
};

This has the virtue of requiring fewer allocations.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.