You can use Iterator::filter_map:
let found: Option<String> = data.iter()
.filter_map(|d| {
match *d {
MyData::DataD { ref data, .. } => Some(data.to_owned()),
_ => None,
}
})
.next();
I don't really like having big statements matchin my iterator chains, so I would usually use a method MyDatato use:
enum MyData {
DataA(String),
DataB(u64),
DataC(bool),
DataD { data: String, val: u32 },
}
impl MyData {
fn as_data_d_data(&self) -> Option<&str> {
match *self {
MyData::DataD { ref data, .. } => Some(data),
_ => None,
}
}
}
fn main() {
let data = vec![
MyData::DataB(42),
MyData::DataD {
data: "meaning of life".to_owned(),
val: 42,
},
MyData::DataC(false),
];
let found: Option<String> = data.iter()
.filter_map(MyData::as_data_d_data)
.map(str::to_owned)
.next();
}
, :
enum MyData {
DataA(String),
DataB(u64),
DataC(bool),
DataD(D),
}
impl MyData {
fn is_a(&self) -> bool {
match *self {
MyData::DataA(..) => true,
_ => false,
}
}
fn as_a(&self) -> Option<&String> {
match *self {
MyData::DataA(ref x) => Some(x),
_ => None,
}
}
fn into_a(self) -> Option<String> {
match self {
MyData::DataA(x) => Some(x),
_ => None,
}
}
}
. , , , ...