I'm attempting to build a sort of HTTP web server as a learning exercise and I'm having trouble trying to make one of my types iterable using a for loop (by implementing IntoIterator
).
So far
I've created a data structure whereby I have a Response
object (meant to model a HTTP response), and that contains a Headers
object (meant to model the HTTP response headers), and that contains a HashMap<String, String>
, representing the actual header values:
use std::collections::HashMap;
struct Headers {
headers: HashMap<String, String>,
}
impl Headers {
pub fn new(headers: HashMap<String, String>) -> Self {
Self { headers }
}
}
struct Response {
headers: Headers,
}
impl Response {
pub fn new(headers: Headers) -> Self {
Self { headers }
}
pub fn headers(&self) -> &Headers {
&self.headers
}
}
Note: The headers
method returns an immutable reference because I just want to read the values. I ideally don't want to copy/clone the headers just so that they can be read.
Aim
What I want to be able to do is something like this:
fn main() {
// just creating an example here
let mut headers = HashMap::new();
headers.insert("foo".to_string(), "one".to_string());
headers.insert("bar".to_string(), "two".to_string());
let response = Response::new(Headers::new(headers));
// this is what I'm aiming for:
for (key, value) in response.headers() {
println!("{}: {}", key, value);
}
}
What I've tried
I've tried a whole bunch of things to get this working, but I've so far failed. The closest I've come so far is to implement IntoIterator
for &Headers
and then call into_iter()
on the hash map:
impl IntoIterator for &Headers {
type Item = (String, String);
type IntoIter = IntoIter<String, String>;
fn into_iter(self) -> Self::IntoIter {
self.headers.into_iter()
}
}
However, this results in an error:
cannot move out of
self.headers
which is behind a shared reference
I've tried searching around and found numerous StackOverflow questions that are similar, but none of them seem to answer my exact question.
Thanks.