I'm trying to abstract a function to take both an instance of std::str::Lines and a mocked version for testing purposes, created out of an array of &str.
My code (which does work) looks something like this:
use std::fs;
#[test]
fn test_day_1() {
let v = ["3", "3", "4", "-2", "-4"].iter().map(|x| *x);
assert_eq!(day1(v), "334-2-4334-2-4");
}
fn day1_pre() -> String {
let contents = fs::read_to_string("day1.txt").expect("error reading file");
day1(contents.lines())
}
fn day1<'a>(lines: impl Iterator<Item = &'a str> + Clone) -> String {
lines
.map(|line| {
let v: Result<i32, _> = line.parse();
v.expect("could not parse line as integer")
})
.cycle()
.take(10)
.map(|x| x.to_string())
.collect()
}
However, this code only works because of the weird .map(|x| *x) inside the test. If I remove that, I get the following error:
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, &str> as Iterator>::Item == &str`
--> src/lib.rs:6:16
|
6 | assert_eq!(day1(v), "334-2-4334-2-4");
| ^^^^ expected `str`, found `&str`
...
14 | fn day1<'a>(lines: impl Iterator<Item = &'a str> + Clone) -> String {
| -------------- required by this bound in `day1`
|
= note: expected reference `&str`
found reference `&&str`
I sort of understand the error. iter returns an &T, which in this case yields a &&str. What I don't understand is why removing the map and replacing iter with into_iter (i.e. let v = ["3", "3", "4", "-2", "-4"].into_iter();) also fails with the same error!
According to the documentation, into_iter iterates over T, thus it should work here?
While writing this post, I also tried replacing the array with a Vec and using into_iter, such that the final result is let v = vec!["3","3","4","-2","-4"].into_iter(); and it worked! However, now I'm even more confused, why would into_iter work for Vec but not for Array?