How to describe this via functions


#1
let query: Option<&HashMap<String, Vec<String>>> = req.get_ref::<UrlEncodedQuery>().ok();
let code_vector: Option<&Vec<String>> = if let Some(query) = query {
    query.get("code")
} else {
    None
};
let code: Option<&String> = if let Some(code_vector) = code_vector {
    Some(&code_vector[0])
} else {
    None
};

Code doesn’t work

let code: Option<&String> = req.get_ref::<UrlEncodedQuery>()
                               .ok()
                               .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                               .map(|codes| &codes[0]);

Errors

error: cannot infer an appropriate lifetime for autoref due to conflicting requirements [E0495]
.and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                                                       ^~~~~~~~~~~
note: first, the lifetime cannot outlive the expression
                           .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                                                                            ^~~~~
note: ...so that auto-reference is valid at the time of borrow
                           .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                                                                            ^~~~~
note: but, the lifetime must be valid for the method call at 78:75...
                           .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                                                                            ^~~~~~~~~~~~~~~~~
note: ...so that method receiver is valid for the method call
                           .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
                                                                            ^~~~~

#2

Does this work any better?

let code: Option<&String> = req.get_ref::<UrlEncodedQuery>()
                               .ok()
                               .and_then(|query| query.get("code"))
                               .map(|codes| &codes[0]);

#3

No. This is why I tried to add types.


#4

Interesting. This fails for me:

use std::collections::HashMap;

fn main() {
    let h = &HashMap::new();
    let query: Result<&HashMap<String, Vec<String>>, ()> = Ok(&h);
    let code: Option<&String> = query
        .ok()
        .and_then(|query: &HashMap<String, Vec<String>>| query.get("code"))
        .map(|codes| &codes[0]);
}

But this works:

use std::collections::HashMap;

fn main() {
    let h = HashMap::new();
    let query: Result<&HashMap<String, Vec<String>>, ()> = Ok(&h);
    let code: Option<&String> = query
        .ok()
        .and_then(|query| query.get("code"))
        .map(|codes| &codes[0]);
}

so I was wondering if you were running into the same problem (which appears to be a bug in rust).


#5

This works. Thanks.


#6

Wait, which works?


#7

This


#8

This may be related to