mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-10 07:04:17 +00:00
feat(text): add FromIterator
impls for Line
and Text
(#967)
This adds `FromIterator` impls for `Line` and `Text` that allow creating `Line` and `Text` instances from iterators of `Span` and `Line` instances, respectively. ```rust let line = Line::from_iter(vec!["Hello".blue(), " world!".green()]); let line: Line = iter::once("Hello".blue()) .chain(iter::once(" world!".green())) .collect(); let text = Text::from_iter(vec!["The first line", "The second line"]); let text: Text = iter::once("The first line") .chain(iter::once("The second line")) .collect(); ```
This commit is contained in:
parent
654949bb00
commit
b5bdde079e
3 changed files with 74 additions and 2 deletions
|
@ -2,7 +2,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use super::StyledGrapheme;
|
||||
use crate::{prelude::*, widgets::Widget};
|
||||
use crate::prelude::*;
|
||||
|
||||
/// A line of text, consisting of one or more [`Span`]s.
|
||||
///
|
||||
|
@ -443,6 +443,15 @@ impl<'a> From<Line<'a>> for String {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T> FromIterator<T> for Line<'a>
|
||||
where
|
||||
T: Into<Span<'a>>,
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
||||
Self::from(iter.into_iter().map(Into::into).collect::<Vec<_>>())
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Line<'_> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
self.render_ref(area, buf);
|
||||
|
@ -488,6 +497,8 @@ impl std::fmt::Display for Line<'_> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::iter;
|
||||
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
|
@ -625,6 +636,32 @@ mod tests {
|
|||
assert_eq!(spans, line.spans);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_iter() {
|
||||
let line = Line::from_iter(vec!["Hello".blue(), " world!".green()]);
|
||||
assert_eq!(
|
||||
line.spans,
|
||||
vec![
|
||||
Span::styled("Hello", Style::new().blue()),
|
||||
Span::styled(" world!", Style::new().green()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn collect() {
|
||||
let line: Line = iter::once("Hello".blue())
|
||||
.chain(iter::once(" world!".green()))
|
||||
.collect();
|
||||
assert_eq!(
|
||||
line.spans,
|
||||
vec![
|
||||
Span::styled("Hello", Style::new().blue()),
|
||||
Span::styled(" world!", Style::new().green()),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_span() {
|
||||
let span = Span::styled("Hello, world!", Style::default().fg(Color::Yellow));
|
||||
|
|
|
@ -4,7 +4,7 @@ use unicode_segmentation::UnicodeSegmentation;
|
|||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use super::StyledGrapheme;
|
||||
use crate::{prelude::*, widgets::Widget};
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Represents a part of a line that is contiguous and where all characters share the same style.
|
||||
///
|
||||
|
|
|
@ -419,6 +419,19 @@ impl<'a> From<Vec<Line<'a>>> for Text<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T> FromIterator<T> for Text<'a>
|
||||
where
|
||||
T: Into<Line<'a>>,
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
||||
let lines = iter.into_iter().map(Into::into).collect();
|
||||
Text {
|
||||
lines,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Extend<T> for Text<'a>
|
||||
where
|
||||
T: Into<Line<'a>>,
|
||||
|
@ -486,6 +499,8 @@ impl<'a> Styled for Text<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::iter;
|
||||
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
|
@ -601,6 +616,26 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_iterator() {
|
||||
let text = Text::from_iter(vec!["The first line", "The second line"]);
|
||||
assert_eq!(
|
||||
text.lines,
|
||||
vec![Line::from("The first line"), Line::from("The second line")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn collect() {
|
||||
let text: Text = iter::once("The first line")
|
||||
.chain(iter::once("The second line"))
|
||||
.collect();
|
||||
assert_eq!(
|
||||
text.lines,
|
||||
vec![Line::from("The first line"), Line::from("The second line")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_iter() {
|
||||
let text = Text::from("The first line\nThe second line");
|
||||
|
|
Loading…
Reference in a new issue