unicode_width_utils/
line_iterator.rs1use crate::UnicodeWidth;
2use crate::WidthIterator;
3use std::borrow::Cow;
4
5#[derive(Debug)]
26pub struct LineIterator<'a, 'b> {
27 uw: &'a UnicodeWidth,
28 input: &'b str,
29 max_width: usize,
30}
31
32impl<'a, 'b> LineIterator<'a, 'b> {
33 pub(crate) fn new(uw: &'a UnicodeWidth, input: &'b str, max_width: usize) -> Self {
35 Self {
36 uw,
37 input,
38 max_width,
39 }
40 }
41}
42
43impl<'a, 'b> Iterator for LineIterator<'a, 'b> {
44 type Item = Cow<'b, str>;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 if self.input.is_empty() {
48 return None;
49 }
50 let mut iter = WidthIterator::new(self.uw, self.input);
51 iter.set_max_width(self.max_width);
52 iter.set_include_at_least_one(true);
53 iter.consume_all();
54 let end_index = iter.input_end_index.unwrap();
55 self.input = &self.input[end_index..];
56 Some(iter.into())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn no_tabs() {
66 let uw = UnicodeWidth::new();
67 let input = "hello world rust";
68 let mut iter = LineIterator::new(&uw, input, 5);
69 assert_eq!(iter.next(), Some(Cow::Borrowed("hello")));
70 assert_eq!(iter.next(), Some(Cow::Borrowed(" worl")));
71 assert_eq!(iter.next(), Some(Cow::Borrowed("d rus")));
72 assert_eq!(iter.next(), Some(Cow::Borrowed("t")));
73 assert_eq!(iter.next(), None);
74 }
75
76 #[test]
77 fn expand_tabs() {
78 let mut uw = UnicodeWidth::new();
79 uw.set_tab_size(4);
80 uw.set_expand_tab(true);
81 let input = "A\tB\tCD";
82 let mut iter = LineIterator::new(&uw, input, 5);
83 assert_eq!(iter.next(), Some(Cow::Owned("A B".to_string())));
84 assert_eq!(iter.next(), Some(Cow::Owned(" C".to_string())));
85 assert_eq!(iter.next(), Some(Cow::Borrowed("D")));
86 assert_eq!(iter.next(), None);
87 }
88
89 #[test]
90 fn cjk_boundary() {
91 let uw = UnicodeWidth::new();
92 let mut iter = LineIterator::new(&uw, "Aあ", 2);
96 assert_eq!(iter.next(), Some(Cow::Borrowed("A")));
97 assert_eq!(iter.next(), Some(Cow::Borrowed("あ")));
98 assert_eq!(iter.next(), None);
99 }
100
101 #[test]
102 fn at_least_one() {
103 let uw = UnicodeWidth::new();
104 let mut iter = LineIterator::new(&uw, "あA", 1);
106 assert_eq!(iter.next(), Some(Cow::Borrowed("あ")));
107 assert_eq!(iter.next(), Some(Cow::Borrowed("A")));
108 assert_eq!(iter.next(), None);
109 }
110}