I have a very basic struct with two fields (may be more) of the same type:
#[derive(Clone, Copy)]
struct F {
x: f32,
y: f32
}
From a user's point of view, a Struct
is very convenient because it has meaningful tags for its elements: f.x
or f.y
rather than v[0]
or t.0
. Because all the elements have the same type, it would also be interesting to be able to treat F
as an IntoIterator
, and map
arbitrary functions to all members of the Struct
. This way I could implement algorithms that work on arrays or vectors for Struct
s (I'm thinking of numeric integration, Runge-Kutta, for example).
So I first implement an iterator for F
:
struct G {
count: u32,
f: F
}
impl G {
fn new(f: F) -> G {
G{count: 0, f: f}
}
}
impl Iterator for G {
type Item = f32;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
match self.count {
1 => Some(self.f.x),
2 => Some(self.f.y),
_ => None
}
}
}
Now implement Fromiter
and IntoIter
for F:
impl FromIterator<f32> for F {
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item = f32> {
let mut i = iter.into_iter();
let x = i.next().unwrap();
let y = i.next().unwrap();
F{x: x, y: y}
}
}
impl IntoIterator for F {
type Item = f32;
type IntoIter = G;
fn into_iter(self) -> G {
G::new(self)
}
}
Now this test passes:
#[test]
fn from_into_iter() {
let f = F{x: 1.0, y: 2.0};
let v: F = f.into_iter().collect();
assert_eq!(f.x, v.x);
assert_eq!(f.y, v.y);
}
But this one does not and panics because of the unwrap
on None
:
#[test]
fn short_from_iter() {
let f = vec![1.0];
let v: F = f.into_iter().collect();
assert_eq!(1.0, v.x);
assert_eq!(0.0, v.y);
}
Certainly, I can take care myself inside into_iter
of the unwrap
s, but I am looking for a way to signal this to the user.
Thanks for your help.