1 | use super::core::display_width; |
2 | |
3 | #[derive (Debug)] |
4 | pub(crate) struct LineWrapper<'w> { |
5 | hard_width: usize, |
6 | line_width: usize, |
7 | carryover: Option<&'w str>, |
8 | } |
9 | |
10 | impl<'w> LineWrapper<'w> { |
11 | pub(crate) fn new(hard_width: usize) -> Self { |
12 | Self { |
13 | hard_width, |
14 | line_width: 0, |
15 | carryover: None, |
16 | } |
17 | } |
18 | |
19 | pub(crate) fn reset(&mut self) { |
20 | self.line_width = 0; |
21 | self.carryover = None; |
22 | } |
23 | |
24 | pub(crate) fn wrap(&mut self, mut words: Vec<&'w str>) -> Vec<&'w str> { |
25 | if self.carryover.is_none() { |
26 | if let Some(word) = words.first() { |
27 | if word.trim().is_empty() { |
28 | self.carryover = Some(*word); |
29 | } else { |
30 | self.carryover = Some("" ); |
31 | } |
32 | } |
33 | } |
34 | |
35 | let mut i = 0; |
36 | while i < words.len() { |
37 | let word = &words[i]; |
38 | let trimmed = word.trim_end(); |
39 | let word_width = display_width(trimmed); |
40 | let trimmed_delta = word.len() - trimmed.len(); |
41 | if i != 0 && self.hard_width < self.line_width + word_width { |
42 | if 0 < i { |
43 | let last = i - 1; |
44 | let trimmed = words[last].trim_end(); |
45 | words[last] = trimmed; |
46 | } |
47 | |
48 | self.line_width = 0; |
49 | words.insert(i, " \n" ); |
50 | i += 1; |
51 | if let Some(carryover) = self.carryover { |
52 | words.insert(i, carryover); |
53 | self.line_width += carryover.len(); |
54 | i += 1; |
55 | } |
56 | } |
57 | self.line_width += word_width + trimmed_delta; |
58 | |
59 | i += 1; |
60 | } |
61 | words |
62 | } |
63 | } |
64 | |