Use Vec to implement the Events iterators

Using `vec::IntoIter` is much simpler than a deeply nested `Chain`,
compiling faster and avoiding the deeper recursion limit reported in
[rust#71359](https://github.com/rust-lang/rust/issues/71359).
This commit is contained in:
Josh Stone 2020-04-22 12:17:27 -07:00 committed by Bodil Stokke
parent 7a884f9561
commit d95ce1a293
1 changed files with 18 additions and 22 deletions

View File

@ -3,7 +3,6 @@
use crate::OutputType; use crate::OutputType;
use htmlescape::encode_attribute; use htmlescape::encode_attribute;
use std::fmt::{Display, Error, Formatter}; use std::fmt::{Display, Error, Formatter};
use std::iter;
/// Trait for event handlers. /// Trait for event handlers.
pub trait EventHandler<T: OutputType + Send, E: Send> { pub trait EventHandler<T: OutputType + Send, E: Send> {
@ -34,23 +33,23 @@ macro_rules! declare_events_struct {
impl<T: Send> Events<T> { impl<T: Send> Events<T> {
pub fn iter(&self) -> impl Iterator<Item = (&'static str, &T)> { pub fn iter(&self) -> impl Iterator<Item = (&'static str, &T)> {
iter::empty() let mut vec = Vec::new();
$( $(
.chain( if let Some(ref value) = self.$name {
self.$name.iter() vec.push((stringify!($name), value));
.map(|value| (stringify!($name), value)) }
)
)* )*
vec.into_iter()
} }
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&'static str, &mut T)> { pub fn iter_mut(&mut self) -> impl Iterator<Item = (&'static str, &mut T)> {
iter::empty() let mut vec = Vec::new();
$( $(
.chain( if let Some(ref mut value) = self.$name {
self.$name.iter_mut() vec.push((stringify!($name), value));
.map(|value| (stringify!($name), value)) }
)
)* )*
vec.into_iter()
} }
} }
@ -58,17 +57,14 @@ macro_rules! declare_events_struct {
type Item = (&'static str, T); type Item = (&'static str, T);
type IntoIter = Box<dyn Iterator<Item = Self::Item>>; type IntoIter = Box<dyn Iterator<Item = Self::Item>>;
fn into_iter(mut self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
Box::new( let mut vec = Vec::new();
iter::empty()
$( $(
.chain( if let Some(value) = self.$name {
iter::once(self.$name.take()) vec.push((stringify!($name), value));
.filter(Option::is_some) }
.map(|value| (stringify!($name), value.unwrap()))
)
)* )*
) Box::new(vec.into_iter())
} }
} }