refactor: define struct WrappedLine instead of anonymous tuple (#608)

It makes the type easier to document, and more obvious for users
This commit is contained in:
Val Lorentz 2023-12-06 22:18:02 +01:00 committed by GitHub
parent dd22e721e3
commit 7ced7c0aa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 13 deletions

View File

@ -6,7 +6,7 @@ use crate::{
style::{Style, Styled}, style::{Style, Styled},
text::{StyledGrapheme, Text}, text::{StyledGrapheme, Text},
widgets::{ widgets::{
reflow::{LineComposer, LineTruncator, WordWrapper}, reflow::{LineComposer, LineTruncator, WordWrapper, WrappedLine},
Block, Widget, Block, Widget,
}, },
}; };
@ -254,8 +254,11 @@ impl<'a> Widget for Paragraph<'a> {
impl<'a> Paragraph<'a> { impl<'a> Paragraph<'a> {
fn render_text<C: LineComposer<'a>>(&self, mut composer: C, area: Rect, buf: &mut Buffer) { fn render_text<C: LineComposer<'a>>(&self, mut composer: C, area: Rect, buf: &mut Buffer) {
let mut y = 0; let mut y = 0;
while let Some((current_line, current_line_width, current_line_alignment)) = while let Some(WrappedLine {
composer.next_line() line: current_line,
width: current_line_width,
alignment: current_line_alignment,
}) = composer.next_line()
{ {
if y >= self.scroll.0 { if y >= self.scroll.0 {
let mut x = get_line_offset(current_line_width, area.width, current_line_alignment); let mut x = get_line_offset(current_line_width, area.width, current_line_alignment);

View File

@ -11,7 +11,16 @@ const NBSP: &str = "\u{00a0}";
/// Cannot implement it as Iterator since it yields slices of the internal buffer (need streaming /// Cannot implement it as Iterator since it yields slices of the internal buffer (need streaming
/// iterators for that). /// iterators for that).
pub trait LineComposer<'a> { pub trait LineComposer<'a> {
fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16, Alignment)>; fn next_line<'lend>(&'lend mut self) -> Option<WrappedLine<'lend, 'a>>;
}
pub struct WrappedLine<'lend, 'text> {
/// One line reflowed to the correct width
pub line: &'lend [StyledGrapheme<'text>],
/// The width of the line
pub width: u16,
/// Whether the line was aligned left or right
pub alignment: Alignment,
} }
/// A state machine that wraps lines on word boundaries. /// A state machine that wraps lines on word boundaries.
@ -56,7 +65,7 @@ where
O: Iterator<Item = (I, Alignment)>, O: Iterator<Item = (I, Alignment)>,
I: Iterator<Item = StyledGrapheme<'a>>, I: Iterator<Item = StyledGrapheme<'a>>,
{ {
fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16, Alignment)> { fn next_line<'lend>(&'lend mut self) -> Option<WrappedLine<'lend, 'a>> {
if self.max_line_width == 0 { if self.max_line_width == 0 {
return None; return None;
} }
@ -200,7 +209,11 @@ where
if let Some(line) = current_line { if let Some(line) = current_line {
self.current_line = line; self.current_line = line;
Some((&self.current_line[..], line_width, self.current_alignment)) Some(WrappedLine {
line: &self.current_line[..],
width: line_width,
alignment: self.current_alignment,
})
} else { } else {
None None
} }
@ -249,7 +262,7 @@ where
O: Iterator<Item = (I, Alignment)>, O: Iterator<Item = (I, Alignment)>,
I: Iterator<Item = StyledGrapheme<'a>>, I: Iterator<Item = StyledGrapheme<'a>>,
{ {
fn next_line(&mut self) -> Option<(&[StyledGrapheme<'a>], u16, Alignment)> { fn next_line<'lend>(&'lend mut self) -> Option<WrappedLine<'lend, 'a>> {
if self.max_line_width == 0 { if self.max_line_width == 0 {
return None; return None;
} }
@ -296,11 +309,11 @@ where
if lines_exhausted { if lines_exhausted {
None None
} else { } else {
Some(( Some(WrappedLine {
&self.current_line[..], line: &self.current_line[..],
current_line_width, width: current_line_width,
current_alignment, alignment: current_alignment,
)) })
} }
} }
} }
@ -360,7 +373,12 @@ mod test {
let mut lines = vec![]; let mut lines = vec![];
let mut widths = vec![]; let mut widths = vec![];
let mut alignments = vec![]; let mut alignments = vec![];
while let Some((styled, width, alignment)) = composer.next_line() { while let Some(WrappedLine {
line: styled,
width,
alignment,
}) = composer.next_line()
{
let line = styled let line = styled
.iter() .iter()
.map(|StyledGrapheme { symbol, .. }| *symbol) .map(|StyledGrapheme { symbol, .. }| *symbol)