AsRef in Option is awkward to use


#1

I’m writing a general function that takes several path options, I’d like these to be AsRef<Path> to make the code easier for the caller. However, one of my paths is optional. I’ve tried wrapping this in an Option, but the end result seems even more awkward to use than if I’d just required a &str or a &Path.

use std::path::Path;

fn main() {
    opt(Some(&"hello".to_string()));
    opt(Some("strval"));

    // opt(None);
    // error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]

    // Make it work by picking some type that fits.
    opt::<&str>(None);
}

fn opt<P: AsRef<Path>>(path: Option<P>) {
    let path = path.as_ref().map(|p| p.as_ref());

    match path {
        None => println!("None"),
        Some(p) => println!("Some {:?}", p),
    }
}

In order to call opt with a None, it is necessary to clarify the type of the Option being passed in. In the case of my real function, this path is one of several path-type arguments, which forces me to have a use case similar to

    my_call::<_, &str, _>(&path1, None, &path2, more_stuff);

Any way that I can make my function accept an optional path, and still nicely AsRef<Path> so that any possible value can work? (One possibility I thought of was to make all of the arguments the same type P, which would eliminate the problem with the None, but make the code less flexible).


#2

You could define a function to return the None case:

fn nopath() -> Option <&'static Path> { None }

#3

Default type parameters will begin informing type inference soon. Try adding

#![feature(default_type_parameter_fallback)]

and

fn opt<P: AsRef<Path> = String>(path: Option<P>) {

#4

I am sorry I resuscitate an ancient thread (but it’s Halloween, so it’s OK, I guess :D) but has there been any development on this?

I found out I can use the turbofish on the None itself (opt(None::<&str>), but it’s still cumbersome, and it’s probably easier to hide the complexity in the function itself and accept an empty string instead.

Thanks!