If we don’t have a title from the user’s CLI arguments, or from the content of the file, then we should ask the user for a title to use.
rprompt is one crate that can handle this interaction for us.
❯ cargo add rprompt
    Updating crates.io index
      Adding rprompt v2.0.2 to dependencies.
    Updating crates.io index
We’ll write a new function called ask_for_filename to encapsulate our usage of rprompt.
prompt_reply will ask the user for input using our string, then return that value to us. If prompt_reply fails, it returns an io::Result which contains the io::Error we’ve been using over and over in this workshop.
fn ask_for_filename() -> io::Result<String> {
    rprompt::prompt_reply(
        "Enter filename
> ",
    )
}
Then we can use it instead of our todo! macro. Similar to Option::map, Result also has a map function we can use to modify the Ok inner value. There’s no trait that dictates the map function implementations, its a convention to be able to map over types that contain values. This works for Options, Results, Iterators, and even third party crates implement this pattern.
Then we can use ? to return the error if there is one.
This all means that filename is a slugified filename, ready to be our destination file.
let filename = match document_title {
    Some(raw_title) => slug::slugify(raw_title),
    None => ask_for_filename()
        .map(|title| slug::slugify(title))?,
};
Our application now asks for input from the user if we don’t have a title.
❯ cargo run -- write
   Compiling garden v0.1.0 (/rust-adventure/digital-garden)
    Finished dev [unoptimized + debuginfo] target(s) in 1.08s
     Running `target/debug/garden write`
[src/lib.rs:17] &filepath = "/Users/chris/garden/.tmpclNu1.md"
Enter filename
> Some new File
[src/lib.rs:41] dest = "/Users/chris/garden/some-new-file.md"
