From d6a91d186575a1c4791b58dfc47e2fa1b978d201 Mon Sep 17 00:00:00 2001 From: Florian Dehau Date: Sun, 3 Sep 2017 13:06:10 +0200 Subject: [PATCH] Fix List lifetime issues Add a new lifetime for the items inside the list --- examples/demo.rs | 25 ++++++------ examples/list.rs | 23 +++++++----- src/widgets/list.rs | 92 ++++++++++++++++++++++----------------------- 3 files changed, 72 insertions(+), 68 deletions(-) diff --git a/examples/demo.rs b/examples/demo.rs index 8d0c4ae2..06500561 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -363,18 +363,19 @@ fn draw_charts(t: &mut Terminal, app: &App, area: &Rect) { let warning_style = Style::default().fg(Color::Yellow); let error_style = Style::default().fg(Color::Magenta); let critical_style = Style::default().fg(Color::Red); - List::new(app.events - .iter() - .map(|&(evt, level)| { - Item::StyledData(format!("{}: {}", level, evt), match level { - "ERROR" => &error_style, - "CRITICAL" => &critical_style, - "WARNING" => &warning_style, - _ => &info_style, - }) - })) - .block(Block::default().borders(border::ALL).title("List")) - .render(t, &chunks[1]); + let events = app.events + .iter() + .map(|&(evt, level)| { + Item::StyledData(format!("{}: {}", level, evt), match level { + "ERROR" => &error_style, + "CRITICAL" => &critical_style, + "WARNING" => &warning_style, + _ => &info_style, + }) + }); + List::new(events) + .block(Block::default().borders(border::ALL).title("List")) + .render(t, &chunks[1]); }); BarChart::default() .block(Block::default().borders(border::ALL).title("Bar chart")) diff --git a/examples/list.rs b/examples/list.rs index 9ced0d83..fbda2678 100644 --- a/examples/list.rs +++ b/examples/list.rs @@ -169,18 +169,21 @@ fn draw(t: &mut Terminal, app: &App) { .highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::Bold)) .highlight_symbol(">") .render(t, &chunks[0]); - List::new(app.events - .iter() - .map(|&(evt, level)| { - Item::StyledData(format!("{}: {}", level, evt), match level { - "ERROR" => &app.error_style, - "CRITICAL" => &app.critical_style, - "WARNING" => &app.warning_style, - _ => &app.info_style, - }) - })) + { + let events = app.events + .iter() + .map(|&(evt, level)| { + Item::StyledData(format!("{}: {}", level, evt), match level { + "ERROR" => &app.error_style, + "CRITICAL" => &app.critical_style, + "WARNING" => &app.warning_style, + _ => &app.info_style, + }) + }); + List::new(events) .block(Block::default().borders(border::ALL).title("List")) .render(t, &chunks[1]); + } }); t.draw().unwrap(); diff --git a/src/widgets/list.rs b/src/widgets/list.rs index e5e4c597..fa19385f 100644 --- a/src/widgets/list.rs +++ b/src/widgets/list.rs @@ -9,23 +9,23 @@ use widgets::{Widget, Block}; use layout::Rect; use style::Style; -pub enum Item<'a, D: 'a> { +pub enum Item<'i, D: 'i> { Data(D), - StyledData(D, &'a Style), + StyledData(D, &'i Style), } -pub struct List<'a, L, D: 'a> - where L: Iterator> +pub struct List<'b, 'i, L, D: 'i> + where L: Iterator> { - block: Option>, + block: Option>, items: L, style: Style, } -impl<'a, L, D> Default for List<'a, L, D> - where L: Iterator> + Default +impl<'b, 'i, L, D> Default for List<'b, 'i, L, D> + where L: Iterator> + Default { - fn default() -> List<'a, L, D> { + fn default() -> List<'b, 'i, L, D> { List { block: None, items: L::default(), @@ -34,10 +34,10 @@ impl<'a, L, D> Default for List<'a, L, D> } } -impl<'a, L, D> List<'a, L, D> - where L: Iterator> +impl<'b, 'i, L, D> List<'b, 'i, L, D> + where L: Iterator> { - pub fn new(items: L) -> List<'a, L, D> { + pub fn new(items: L) -> List<'b, 'i, L, D> { List { block: None, items: items, @@ -45,26 +45,26 @@ impl<'a, L, D> List<'a, L, D> } } - pub fn block(&'a mut self, block: Block<'a>) -> &mut List<'a, L, D> { + pub fn block(&'b mut self, block: Block<'b>) -> &mut List<'b, 'i, L, D> { self.block = Some(block); self } - pub fn items>>(&'a mut self, - items: L) - -> &mut List<'a, L, D> { - self.items = items; + pub fn items(&'b mut self, items: I) -> &mut List<'b, 'i, L, D> + where I: IntoIterator, IntoIter = L> + { + self.items = items.into_iter(); self } - pub fn style(&'a mut self, style: Style) -> &mut List<'a, L, D> { + pub fn style(&'b mut self, style: Style) -> &mut List<'b, 'i, L, D> { self.style = style; self } } -impl<'a, L, D> Widget for List<'a, L, D> - where L: Iterator>, +impl<'b, 'i, L, D> Widget for List<'b, 'i, L, D> + where L: Iterator>, D: Display { fn draw(&mut self, area: &Rect, buf: &mut Buffer) { @@ -126,10 +126,10 @@ impl<'a, L, D> Widget for List<'a, L, D> /// .highlight_symbol(">>"); /// # } /// ``` -pub struct SelectableList<'a> { - block: Option>, +pub struct SelectableList<'b> { + block: Option>, /// Items to be displayed - items: Vec<&'a str>, + items: Vec<&'b str>, /// Index of the one selected selected: Option, /// Base style of the widget @@ -137,11 +137,11 @@ pub struct SelectableList<'a> { /// Style used to render selected item highlight_style: Style, /// Symbol in front of the selected item (Shift all items to the right) - highlight_symbol: Option<&'a str>, + highlight_symbol: Option<&'b str>, } -impl<'a> Default for SelectableList<'a> { - fn default() -> SelectableList<'a> { +impl<'b> Default for SelectableList<'b> { + fn default() -> SelectableList<'b> { SelectableList { block: None, items: Vec::new(), @@ -153,41 +153,41 @@ impl<'a> Default for SelectableList<'a> { } } -impl<'a> SelectableList<'a> { - pub fn block(&'a mut self, block: Block<'a>) -> &mut SelectableList<'a> { +impl<'b> SelectableList<'b> { + pub fn block(&'b mut self, block: Block<'b>) -> &mut SelectableList<'b> { self.block = Some(block); self } - pub fn items(&'a mut self, items: &'a [I]) -> &mut SelectableList<'a> - where I: AsRef + 'a + pub fn items(&'b mut self, items: &'b [I]) -> &mut SelectableList<'b> + where I: AsRef + 'b { self.items = items.iter().map(|i| i.as_ref()).collect::>(); self } - pub fn style(&'a mut self, style: Style) -> &mut SelectableList<'a> { + pub fn style(&'b mut self, style: Style) -> &mut SelectableList<'b> { self.style = style; self } - pub fn highlight_symbol(&'a mut self, highlight_symbol: &'a str) -> &mut SelectableList<'a> { + pub fn highlight_symbol(&'b mut self, highlight_symbol: &'b str) -> &mut SelectableList<'b> { self.highlight_symbol = Some(highlight_symbol); self } - pub fn highlight_style(&'a mut self, highlight_style: Style) -> &mut SelectableList<'a> { + pub fn highlight_style(&'b mut self, highlight_style: Style) -> &mut SelectableList<'b> { self.highlight_style = highlight_style; self } - pub fn select(&'a mut self, index: usize) -> &'a mut SelectableList<'a> { + pub fn select(&'b mut self, index: usize) -> &'b mut SelectableList<'b> { self.selected = Some(index); self } } -impl<'a> Widget for SelectableList<'a> { +impl<'b> Widget for SelectableList<'b> { fn draw(&mut self, area: &Rect, buf: &mut Buffer) { let list_area = match self.block { @@ -214,17 +214,17 @@ impl<'a> Widget for SelectableList<'a> { }; // Render items - List::new(self.items - .iter() - .enumerate() - .map(|(i, item)| if i == selected { - Item::StyledData(format!("{} {}", highlight_symbol, item), - highlight_style) - } else { - Item::StyledData(format!("{} {}", blank_symbol, item), &self.style) - }) - .skip(offset as usize)) - .block(self.block.unwrap_or_default()) - .draw(area, buf); + let items = self.items + .iter() + .enumerate() + .map(|(i, item)| if i == selected { + Item::StyledData(format!("{} {}", highlight_symbol, item), highlight_style) + } else { + Item::StyledData(format!("{} {}", blank_symbol, item), &self.style) + }) + .skip(offset as usize); + List::new(items) + .block(self.block.unwrap_or_default()) + .draw(area, buf); } }