0

I'm using restson to make REST calls.

Reston allows you to make a Vec of query params to pass to the REST call. This is the example they provide in their documentation:

let query = vec![("a","2"), ("b","abcd")];
let data: HttpBinAnything = client.get_with(1234, &query).unwrap();

In my case I need to pass a parameter to deal with pagination:

  • On the first request no parameter needs to be supplied.
  • The response body contains an "after" field
  • Requests to get the next page need to supply the after field as a query parameter.

If I have a method like this it compiles:

fn fetch_page(client: &mut RestClient, after: Option<String>) -> Result<Page, Error> {
   match after {
       Some(s) => {
           let query = vec![("after", s.as_str())];
           client.get_with(&query)
       }
       None => {
           let query = vec![];
           client.get_with(&query)
       }
   }
}

If I try to use anything other than pattern matching it fails. For example the following code:

fn fetch_page(client: &mut RestClient, after: Option<String>) -> Result<Page, Error> {
    let query = after.map_or(vec![], |s| vec![("after", s.as_str())] );
    client.get_with(&query)
}

Results in the following error:

error[E0515]: cannot return value referencing function parameter `s`
  --> src/reddit_scrape.rs:53:42
   |
53 |     let query = after.map_or(vec![], |s| vec![("after", s.as_str())] );
   |                                          ^^^^^^^^^^^^^^^-^^^^^^^^^^^
   |                                          |              |
   |                                          |              `s` is borrowed here
   |                                          returns a value referencing data owned by the current function
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ciferkey
  • 2,064
  • 3
  • 20
  • 28
  • 1
    It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Aug 07 '19 at 20:38
  • Attempting to guess at filling in the rest of the code yields the errors ``cannot find type `Page` in this scope`` and ``this function takes 2 parameters but 1 parameter was supplied`` – Shepmaster Aug 07 '19 at 20:40
  • 1
    It looks like your question might be answered by the answers of [Converting from Option to Option<&str>](https://stackoverflow.com/q/31233938/155423); [How do I borrow a reference to what is inside an Option?](https://stackoverflow.com/q/22282117/155423); [Why does Option.as_ref() not deref to Option<&str>?](https://stackoverflow.com/q/44163624/155423); If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Aug 07 '19 at 20:43
  • The duplicates applied to your question: `let query = after.as_ref().map_or(vec![], |s| vec![("after", s.as_str())]);` – Shepmaster Aug 07 '19 at 20:49
  • The "what's different" is [match ergonomics](https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md). This is discussed in some duplicate answers, but see also: [Why does pattern matching on &Option yield something of type Some(&T)?](https://stackoverflow.com/q/55625001/155423); [Is there any difference between matching on a reference to a pattern or a dereferenced value?](https://stackoverflow.com/q/43370054/155423); [How can the ref keyword be avoided when pattern matching in a function taking &self or &mut self?](https://stackoverflow.com/q/55130932/155423). – Shepmaster Aug 07 '19 at 20:52

0 Answers0