I just started writing in Rust and I am writing a small program to learn Rust and the package Reqwest.
Here's my little program. I don't understand why changing from HashMap<&str, &str> to HashMap<String, String> can make it work whilst cookie still only lives within the scope? I've commented my doubts along the code as well.
use reqwest::cookie::Jar;
use reqwest::{Client, Url};
use std::sync::Arc;
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let jar = Jar::default();
let raw_url = "https://www.google.com";
let url = Url::parse("https://www.google.com").unwrap();
jar.add_cookie_str("session=1", &url);
let jar = Arc::new(jar);
let client_builder = Client::builder();
let client = client_builder
.cookie_provider(Arc::clone(&jar))
.build()?;
let response = client.get(raw_url).send().await?;
let headers: &HeadersMap = response.headers();
let cookies: Impl Iterator<Item=Cookie>+Sized = response.cookies();
// let mut cookie_map = HashMap::<String, String>::new(); // this would work;
let mut cookie_map = HashMap::<&str, &str>::new(); // impl<'a> Cookie<'a>
let mut header_map = HashMap::<&str, &str>::new(); // live as long as the programme
for cookie in cookies { // declared borrowed value here, hence the lifetime kicks in
// Error: cookie does not live long enough
cookie_map.insert(cookie.name(), cookie.value());
// cookie_map.insert(cookie.name().to_string(), cookie.value().to_string());
// with `to_string` we have taken ownership of the value; is this why it's working?
}
// cookie dropped while still borrowed here;
// kv pairs are both borrowed values that have a lifetime `'a` which ends here
// and cookie_map apparently continues to exist, hence the error (this is my guess)
for (k, v) in headers.iter() {
match v.to_str() {
Ok(val) => header_map.insert(k.as_str(), val),
Err(_) => panic!()
};
}
for (hk, kv) in header_map {
println!("header name is {}, header value is {}", hk, kv);
}
Ok(())
}
Here's the cargo.toml:
[package]
name = "tester"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "tester"
test = false
bench = false
[dependencies]
reqwest = { version = "0.11", features = ["blocking", "json", "cookies"] }
tokio = { version = "1", features = ["full"] }
futures = "0.3"
reqwest_cookie_store = "0.7.0"
cargo check error log is provided here:
error[E0597]: `cookie` does not live long enough
--> src/tools/fetcher.rs:32:32
|
31 | for cookie in cookies {
| ------ binding `cookie` declared here
32 | cookie_map.insert(cookie.name(), cookie.value());
| ---------- ^^^^^^ borrowed value does not live long enough
| |
| borrow later used here
33 | }
| - `cookie` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
error: could not compile `data_fetcher` (bin "data_fetcher") due to 1 previous error
cargo check. As @cafce25 said, supplying a comment with a downvote is not required, for reasons explained in the Q&A they linked. I do try to leave a comment when I downvote (most of the times). And for the record, I am not the downvoter here. I don't think this should matter for you thought, nor I think you should take a single downvote into heart (or really, any number of downvotes). A single downvote means one user has found your question to...ReqwestAPI quoted forcookieshowed more evidence. Functional example has been provided, I don't see how it's unclear or not useful. @ChayimFriedman But thank you for coming back for a reason.