Implementing From<SetCookie> for Cookie for hyper


#1

Following this thread, I tried to implement the From<SetCookie> for Cookie for hyper (reqwest just using the hyper implementations of the headers). I tried this and it send back this cryptic error :

error[E0277]: the trait bound std::vec::Vec<std::borrow::Cow<'_, &str>>: std::iter::FromIterator<&str> is not satisfied

75 |                 values = fi.split('=').collect::<Vec<Cow<&str>>>();
       |                                        ^^^^^^^ a collection of type `std::vec::Vec<std::borrow::Cow<'_, &str>>` cannot be built from an iterator over elements of type `&str`
       |
       = help: the trait `std::iter::FromIterator<&str>` is not implemented for `std::vec::Vec<std::borrow::Cow<'_, &str>>`


error[E0277]: the trait bound `std::borrow::Cow<'static, str>: _IMPL_DESERIALIZE_FOR_Config::_serde::export::From<std::borrow::Cow<'_, &str>>` is not satisfied
  --> src/main.rs:76:24
   |
76 |                 Cookie.set(values[0], values[1]);
   |                        ^^^ the trait `_IMPL_DESERIALIZE_FOR_Config::_serde::export::From<std::borrow::Cow<'_, &str>>` is not implemented for `std::borrow::Cow<'static, str>`
   |
   = help: the following implementations were found:
             <std::borrow::Cow<'a, [u8]> as _IMPL_DESERIALIZE_FOR_Config::_serde::export::From<url::<unnamed>::PercentDecode<'a>>>
             <std::borrow::Cow<'a, str> as _IMPL_DESERIALIZE_FOR_Config::_serde::export::From<url::<unnamed>::PercentEncode<'a, E>>>
             <std::borrow::Cow<'a, str> as _IMPL_DESERIALIZE_FOR_Config::_serde::export::From<std::string::String>>
             <std::borrow::Cow<'a, str> as _IMPL_DESERIALIZE_FOR_Config::_serde::export::From<&'a str>>
           and 5 others
   = note: required because of the requirements on the impl of `_IMPL_DESERIALIZE_FOR_Config::_serde::export::Into<std::borrow::Cow<'static, str>>` for `std::borrow::Cow<'_, &str>`

Why is doing that ? How could I fix that ?
Bonus question : How could I “rustify” the code (i.e. putting iterator everywhere ? :wink: ) ?


#2

It looks likeCookie::set wants Cow<'static, str> and you’re giving it Cow<'_, str>. That underscore basically means you have some non-static lifetime. That’s because you’re getting string slices that refer to String instances created within that function. So those str slices are not 'static. A &'static str is basically a compile-time constant/literal string, it’s not something you can dynamically create at runtime.


#3

Thanks for taking the time to answer my question!
Okay, how can I fix that?


#4

The easiest is to call Cookie::set with owned String values. So perhaps change Cookie.set(values[0], values[1]); to Cookie.set(values[0].to_string(), values[1].to_string());


#5

Poorfully it throws back error[E0597]: ``fi`` does not live long enough

   |
75 |                 values = fi.split('=').collect::<Vec<&str>>();
   |                          -- borrow occurs here
76 |                 Cookie.set(values[0].to_string(), values[1].to_string());
77 |             }
   |             ^ `fi` dropped here while still borrowed
78 |         }
79 |     }
   |     - borrowed value needs to live until here

#6

Right - you can’t have values live longer than the str slices it holds because those slices are into strings that die in the loop.

You don’t need to collect into a vec though. Just take the Split, which is an iterator, and get the two elements via next calls. Something like:

let mut split = ...;
Cookie::set(split.next().unwrap().to_string(), split.next().unwrap().to_string());

You may want to add error handling rather than unwrap but that’s the gist.