1use std::str;
68use std::sync::Arc;
69
70use crate::slice::{RSEnum, RopeSlice};
71use crate::str_utils::{
72 byte_to_line_idx, char_to_byte_idx, count_chars, count_utf16_surrogates, ends_with_line_break,
73 last_line_start_byte_idx, line_to_byte_idx, trim_line_break,
74};
75use crate::tree::{Count, Node, TextInfo};
76
77#[derive(Debug, Clone)]
81pub struct Bytes<'a> {
82 chunk_iter: Chunks<'a>,
83 cur_chunk: &'a [u8],
84 byte_idx: usize,
85 last_call_was_prev_impl: bool,
86 bytes_total: usize,
87 bytes_remaining: usize,
88 is_reversed: bool,
89}
90
91impl<'a> Bytes<'a> {
92 pub(crate) fn new(node: &Arc<Node>) -> Bytes {
93 let mut chunk_iter = Chunks::new(node);
94 let cur_chunk = if let Some(chunk) = chunk_iter.next() {
95 chunk
96 } else {
97 ""
98 };
99 Bytes {
100 chunk_iter: chunk_iter,
101 cur_chunk: cur_chunk.as_bytes(),
102 byte_idx: 0,
103 last_call_was_prev_impl: false,
104 bytes_total: node.text_info().bytes as usize,
105 bytes_remaining: node.text_info().bytes as usize,
106 is_reversed: false,
107 }
108 }
109
110 #[inline(always)]
111 pub(crate) fn new_with_range(
112 node: &Arc<Node>,
113 byte_idx_range: (usize, usize),
114 char_idx_range: (usize, usize),
115 line_break_idx_range: (usize, usize),
116 ) -> Bytes {
117 Bytes::new_with_range_at(
118 node,
119 byte_idx_range.0,
120 byte_idx_range,
121 char_idx_range,
122 line_break_idx_range,
123 )
124 }
125
126 pub(crate) fn new_with_range_at(
127 node: &Arc<Node>,
128 at_byte: usize,
129 byte_idx_range: (usize, usize),
130 char_idx_range: (usize, usize),
131 line_break_idx_range: (usize, usize),
132 ) -> Bytes {
133 let (mut chunk_iter, mut chunk_byte_start, _, _) = Chunks::new_with_range_at_byte(
134 node,
135 at_byte,
136 byte_idx_range,
137 char_idx_range,
138 line_break_idx_range,
139 );
140
141 let cur_chunk = if byte_idx_range.0 == byte_idx_range.1 {
142 ""
143 } else if at_byte < byte_idx_range.1 {
144 chunk_iter.next().unwrap()
145 } else {
146 let chunk = chunk_iter.prev().unwrap();
147 chunk_iter.next();
148 chunk_byte_start -= chunk.len();
149 chunk
150 };
151
152 Bytes {
153 chunk_iter: chunk_iter,
154 cur_chunk: cur_chunk.as_bytes(),
155 byte_idx: at_byte - chunk_byte_start,
156 last_call_was_prev_impl: false,
157 bytes_total: byte_idx_range.1 - byte_idx_range.0,
158 bytes_remaining: byte_idx_range.1 - at_byte,
159 is_reversed: false,
160 }
161 }
162
163 #[inline(always)]
164 pub(crate) fn from_str(text: &str) -> Bytes {
165 Bytes::from_str_at(text, 0)
166 }
167
168 pub(crate) fn from_str_at(text: &str, byte_idx: usize) -> Bytes {
169 let mut chunk_iter = Chunks::from_str(text, false);
170 let cur_chunk = if let Some(chunk) = chunk_iter.next() {
171 chunk
172 } else {
173 ""
174 };
175 Bytes {
176 chunk_iter: chunk_iter,
177 cur_chunk: cur_chunk.as_bytes(),
178 byte_idx: byte_idx,
179 last_call_was_prev_impl: false,
180 bytes_total: text.len(),
181 bytes_remaining: text.len() - byte_idx,
182 is_reversed: false,
183 }
184 }
185
186 #[inline]
191 pub fn reverse(&mut self) {
192 self.is_reversed = !self.is_reversed;
193 }
194
195 #[inline]
208 #[must_use]
209 pub fn reversed(mut self) -> Bytes<'a> {
210 self.reverse();
211 self
212 }
213
214 #[inline(always)]
218 pub fn prev(&mut self) -> Option<u8> {
219 if !self.is_reversed {
220 self.prev_impl()
221 } else {
222 self.next_impl()
223 }
224 }
225
226 #[inline]
227 fn prev_impl(&mut self) -> Option<u8> {
228 if !self.last_call_was_prev_impl {
230 self.chunk_iter.prev();
231 self.last_call_was_prev_impl = true;
232 }
233
234 if self.byte_idx == 0 {
236 if let Some(chunk) = self.chunk_iter.prev() {
237 self.cur_chunk = chunk.as_bytes();
238 self.byte_idx = self.cur_chunk.len();
239 } else {
240 return None;
241 }
242 }
243
244 self.byte_idx -= 1;
246 self.bytes_remaining += 1;
247 return Some(self.cur_chunk[self.byte_idx]);
248 }
249
250 #[inline]
251 fn next_impl(&mut self) -> Option<u8> {
252 if self.last_call_was_prev_impl {
254 self.chunk_iter.next();
255 self.last_call_was_prev_impl = false;
256 }
257
258 if self.byte_idx >= self.cur_chunk.len() {
260 if let Some(chunk) = self.chunk_iter.next() {
261 self.cur_chunk = chunk.as_bytes();
262 self.byte_idx = 0;
263 } else {
264 return None;
265 }
266 }
267
268 let byte = self.cur_chunk[self.byte_idx];
270 self.byte_idx += 1;
271 self.bytes_remaining -= 1;
272 return Some(byte);
273 }
274}
275
276impl<'a> Iterator for Bytes<'a> {
277 type Item = u8;
278
279 #[inline(always)]
283 fn next(&mut self) -> Option<u8> {
284 if !self.is_reversed {
285 self.next_impl()
286 } else {
287 self.prev_impl()
288 }
289 }
290
291 fn size_hint(&self) -> (usize, Option<usize>) {
292 let remaining = if !self.is_reversed {
293 self.bytes_remaining
294 } else {
295 self.bytes_total - self.bytes_remaining
296 };
297 (remaining, Some(remaining))
298 }
299}
300
301impl<'a> ExactSizeIterator for Bytes<'a> {}
302
303#[derive(Debug, Clone)]
307pub struct Chars<'a> {
308 chunk_iter: Chunks<'a>,
309 cur_chunk: &'a str,
310 byte_idx: usize,
311 last_call_was_prev_impl: bool,
312 chars_total: usize,
313 chars_remaining: usize,
314 is_reversed: bool,
315}
316
317impl<'a> Chars<'a> {
318 pub(crate) fn new(node: &Arc<Node>) -> Chars {
319 let mut chunk_iter = Chunks::new(node);
320 let cur_chunk = if let Some(chunk) = chunk_iter.next() {
321 chunk
322 } else {
323 ""
324 };
325 Chars {
326 chunk_iter: chunk_iter,
327 cur_chunk: cur_chunk,
328 byte_idx: 0,
329 last_call_was_prev_impl: false,
330 chars_total: node.text_info().chars as usize,
331 chars_remaining: node.text_info().chars as usize,
332 is_reversed: false,
333 }
334 }
335
336 #[inline(always)]
337 pub(crate) fn new_with_range(
338 node: &Arc<Node>,
339 byte_idx_range: (usize, usize),
340 char_idx_range: (usize, usize),
341 line_break_idx_range: (usize, usize),
342 ) -> Chars {
343 Chars::new_with_range_at(
344 node,
345 char_idx_range.0,
346 byte_idx_range,
347 char_idx_range,
348 line_break_idx_range,
349 )
350 }
351
352 pub(crate) fn new_with_range_at(
353 node: &Arc<Node>,
354 at_char: usize,
355 byte_idx_range: (usize, usize),
356 char_idx_range: (usize, usize),
357 line_break_idx_range: (usize, usize),
358 ) -> Chars {
359 let (mut chunk_iter, _, mut chunk_char_start, _) = Chunks::new_with_range_at_char(
360 node,
361 at_char,
362 byte_idx_range,
363 char_idx_range,
364 line_break_idx_range,
365 );
366
367 let cur_chunk = if char_idx_range.0 == char_idx_range.1 {
368 ""
369 } else if at_char < char_idx_range.1 {
370 chunk_iter.next().unwrap()
371 } else {
372 let chunk = chunk_iter.prev().unwrap();
373 chunk_iter.next();
374 chunk_char_start =
375 (node.get_chunk_at_char(at_char - 1).1.chars as usize).max(char_idx_range.0);
376 chunk
377 };
378
379 Chars {
380 chunk_iter: chunk_iter,
381 cur_chunk: cur_chunk,
382 byte_idx: char_to_byte_idx(cur_chunk, at_char - chunk_char_start),
383 last_call_was_prev_impl: false,
384 chars_total: char_idx_range.1 - char_idx_range.0,
385 chars_remaining: char_idx_range.1 - at_char,
386 is_reversed: false,
387 }
388 }
389
390 #[inline(always)]
391 pub(crate) fn from_str(text: &str) -> Chars {
392 Chars::from_str_at(text, 0)
393 }
394
395 pub(crate) fn from_str_at(text: &str, char_idx: usize) -> Chars {
396 let mut chunk_iter = Chunks::from_str(text, false);
397 let cur_chunk = if let Some(chunk) = chunk_iter.next() {
398 chunk
399 } else {
400 ""
401 };
402 let start_byte_idx = char_to_byte_idx(text, char_idx);
403 let chars_remaining = count_chars(&text[start_byte_idx..]);
404
405 Chars {
406 chunk_iter: chunk_iter,
407 cur_chunk: cur_chunk,
408 byte_idx: start_byte_idx,
409 last_call_was_prev_impl: false,
410 chars_total: chars_remaining + count_chars(&text[..start_byte_idx]),
411 chars_remaining: chars_remaining,
412 is_reversed: false,
413 }
414 }
415
416 #[inline]
421 pub fn reverse(&mut self) {
422 self.is_reversed = !self.is_reversed;
423 }
424
425 #[inline]
438 #[must_use]
439 pub fn reversed(mut self) -> Chars<'a> {
440 self.reverse();
441 self
442 }
443
444 #[inline(always)]
448 pub fn prev(&mut self) -> Option<char> {
449 if !self.is_reversed {
450 self.prev_impl()
451 } else {
452 self.next_impl()
453 }
454 }
455
456 #[inline]
457 fn prev_impl(&mut self) -> Option<char> {
458 if !self.last_call_was_prev_impl {
460 self.chunk_iter.prev();
461 self.last_call_was_prev_impl = true;
462 }
463
464 if self.byte_idx == 0 {
466 if let Some(chunk) = self.chunk_iter.prev() {
467 self.cur_chunk = chunk;
468 self.byte_idx = self.cur_chunk.len();
469 } else {
470 return None;
471 }
472 }
473
474 self.byte_idx -= 1;
477 while !self.cur_chunk.is_char_boundary(self.byte_idx) {
478 self.byte_idx -= 1;
479 }
480 self.chars_remaining += 1;
481 return (&self.cur_chunk[self.byte_idx..]).chars().next();
482 }
483
484 #[inline]
485 fn next_impl(&mut self) -> Option<char> {
486 if self.last_call_was_prev_impl {
488 self.chunk_iter.next();
489 self.last_call_was_prev_impl = false;
490 }
491
492 if self.byte_idx >= self.cur_chunk.len() {
494 if let Some(chunk) = self.chunk_iter.next() {
495 self.cur_chunk = chunk;
496 self.byte_idx = 0;
497 } else {
498 return None;
499 }
500 }
501
502 let start = self.byte_idx;
505 self.byte_idx += 1;
506 while !self.cur_chunk.is_char_boundary(self.byte_idx) {
507 self.byte_idx += 1;
508 }
509 self.chars_remaining -= 1;
510 return (&self.cur_chunk[start..]).chars().next();
511 }
512}
513
514impl<'a> Iterator for Chars<'a> {
515 type Item = char;
516
517 #[inline(always)]
521 fn next(&mut self) -> Option<char> {
522 if !self.is_reversed {
523 self.next_impl()
524 } else {
525 self.prev_impl()
526 }
527 }
528
529 fn size_hint(&self) -> (usize, Option<usize>) {
530 let remaining = if !self.is_reversed {
531 self.chars_remaining
532 } else {
533 self.chars_total - self.chars_remaining
534 };
535 (remaining, Some(remaining))
536 }
537}
538
539impl<'a> ExactSizeIterator for Chars<'a> {}
540
541#[derive(Debug, Clone)]
550pub struct Lines<'a> {
551 iter: LinesEnum<'a>,
552 is_reversed: bool,
553 text: &'a str,
555 byte_idx: usize,
557 at_end: bool,
558 line_idx: usize,
559 total_lines: usize,
560}
561
562#[derive(Debug, Clone)]
563enum LinesEnum<'a> {
564 Full {
565 node_stack: Vec<(&'a Arc<Node>, usize)>,
572 leaf_byte_idx: u32,
574 total_bytes: usize,
576 },
577 Light,
578}
579
580impl<'a> Lines<'a> {
581 #[inline(always)]
582 pub(crate) fn new(node: &Arc<Node>) -> Lines {
583 let info = node.text_info();
584 Lines::new_with_range_at(
585 node,
586 0,
587 (0, info.bytes as usize),
588 (0, info.line_breaks as usize + 1),
589 )
590 }
591
592 #[inline(always)]
593 pub(crate) fn new_with_range(
594 node: &Arc<Node>,
595 byte_idx_range: (usize, usize),
596 line_idx_range: (usize, usize),
597 ) -> Lines {
598 Lines::new_with_range_at(node, line_idx_range.0, byte_idx_range, line_idx_range)
599 }
600
601 pub(crate) fn new_with_range_at(
602 node: &Arc<Node>,
603 line: usize,
604 byte_idx_range: (usize, usize),
605 line_idx_range: (usize, usize),
606 ) -> Lines {
607 debug_assert!(node.is_char_boundary(byte_idx_range.0));
608 debug_assert!(node.is_char_boundary(byte_idx_range.1));
609 debug_assert!(line >= line_idx_range.0);
610
611 let total_lines = line_idx_range.1 - line_idx_range.0;
613
614 if byte_idx_range.0 == byte_idx_range.1 {
616 return Lines {
617 iter: LinesEnum::Light,
618 text: "",
619 at_end: false,
620 is_reversed: false,
621 byte_idx: 0,
622 line_idx: 0,
623 total_lines: 1,
624 };
625 }
626
627 if node.is_leaf() {
629 let text = &node.leaf_text()[byte_idx_range.0..byte_idx_range.1];
630 return Lines::from_str_at(text, line - line_idx_range.0, total_lines);
631 }
632
633 let mut start_byte_idx = byte_idx_range.0;
635 let mut end_byte_idx = byte_idx_range.1;
636 let mut line_idx = line;
637 let mut chunk_byte_start = 0;
638 let mut node_stack: Vec<(&Arc<Node>, usize)> = Vec::new();
639 let mut node_ref = node;
640 loop {
641 match **node_ref {
642 Node::Internal(ref children) => {
645 let (child_i, acc) = children.search_by(|_, end_info| {
647 if (end_info.bytes as usize) >= end_byte_idx {
648 true
649 } else if line_idx <= (end_info.line_breaks as usize) {
650 (end_info.bytes as usize) > start_byte_idx
651 } else {
652 false
653 }
654 });
655
656 start_byte_idx = start_byte_idx.saturating_sub(acc.bytes as usize);
658 end_byte_idx -= acc.bytes as usize;
659 line_idx -= acc.line_breaks as usize;
660 chunk_byte_start += acc.bytes as usize;
661
662 node_stack.push((node_ref, child_i));
664 node_ref = &children.nodes()[child_i];
665 }
666
667 Node::Leaf(ref text) => {
669 let leaf_byte_idx = line_to_byte_idx(text, line_idx)
670 .max(start_byte_idx)
671 .min(end_byte_idx);
672
673 let res = Lines {
674 iter: LinesEnum::Full {
675 node_stack,
676 leaf_byte_idx: leaf_byte_idx as u32,
677 total_bytes: byte_idx_range.1 - byte_idx_range.0,
678 },
679 is_reversed: false,
680 text,
681 byte_idx: chunk_byte_start + leaf_byte_idx - byte_idx_range.0,
682 at_end: leaf_byte_idx == end_byte_idx
683 && line_idx > byte_to_line_idx(&text[..end_byte_idx], end_byte_idx),
684 line_idx: line - line_idx_range.0,
685 total_lines,
686 };
687
688 return res;
689 }
690 }
691 }
692 }
693
694 #[doc(hidden)]
698 pub fn from_str_pt(text: &str) -> Lines {
699 let line_count = byte_to_line_idx(text, text.len()) + 1;
700 Lines::from_str(text, line_count)
701 }
702
703 pub(crate) fn from_str(text: &str, lines: usize) -> Lines {
704 Lines {
705 iter: LinesEnum::Light,
706 is_reversed: false,
707 text: text,
708 byte_idx: 0,
709 at_end: false,
710 line_idx: 0,
711 total_lines: lines,
712 }
713 }
714
715 pub(crate) fn from_str_at(text: &str, line: usize, lines: usize) -> Lines {
716 Lines {
717 iter: LinesEnum::Light,
718 is_reversed: false,
719 text: text,
720 byte_idx: line_to_byte_idx(text, line),
721 at_end: line >= lines,
722 line_idx: line.min(lines),
723 total_lines: lines,
724 }
725 }
726 #[inline]
731 pub fn reverse(&mut self) {
732 self.is_reversed = !self.is_reversed;
733 }
734
735 #[inline]
748 #[must_use]
749 pub fn reversed(mut self) -> Lines<'a> {
750 self.reverse();
751 self
752 }
753
754 #[inline(always)]
759 pub fn prev(&mut self) -> Option<RopeSlice<'a>> {
760 if self.is_reversed {
761 self.next_impl()
762 } else {
763 self.prev_impl()
764 }
765 }
766
767 fn prev_impl(&mut self) -> Option<RopeSlice<'a>> {
768 match *self {
769 Lines {
770 iter:
771 LinesEnum::Full {
772 ref mut node_stack,
773 ref mut leaf_byte_idx,
774 ..
775 },
776 ref mut byte_idx,
777 ref mut text,
778 ref mut at_end,
779 ref mut line_idx,
780 ..
781 } => {
782 let tail = &text[..*leaf_byte_idx as usize];
783
784 let ends_with_line_break = if std::mem::take(at_end) {
790 if ends_with_line_break(tail) {
791 *line_idx -= 1;
792 return Some(RopeSlice(RSEnum::Light {
793 text: "",
794 char_count: 0,
795 utf16_surrogate_count: 0,
796 line_break_count: 0,
797 }));
798 }
799 false
800 } else if *byte_idx == 0 {
801 return None;
802 } else {
803 true
804 };
805
806 *line_idx -= 1;
807
808 let (line_start_idx, line_inside_chunk) = {
812 let line_start = last_line_start_byte_idx(trim_line_break(tail));
813 let line_len = *leaf_byte_idx as usize - line_start;
814 if line_len >= *byte_idx {
815 (*leaf_byte_idx as usize - *byte_idx, true)
816 } else {
817 (line_start, line_start > 0)
818 }
819 };
820
821 let chunk_line = &tail[line_start_idx..];
822 *byte_idx -= chunk_line.len();
823
824 if line_inside_chunk {
826 *leaf_byte_idx = line_start_idx as u32;
827 return Some(RopeSlice(RSEnum::Light {
828 text: chunk_line,
829 char_count: count_chars(chunk_line) as Count,
830 utf16_surrogate_count: count_utf16_surrogates(chunk_line) as Count,
831 line_break_count: ends_with_line_break as Count,
832 }));
833 }
834
835 let mut shared_parent = node_stack.len() - 1;
841 let mut pos_in_shared_parent = {
842 let (parent, child_i) = *node_stack.last().unwrap();
843 parent.children().info()[..child_i]
844 .iter()
845 .fold(TextInfo::new(), |res, it| res + *it)
846 };
847 let mut len = TextInfo::from_str(tail);
848 pos_in_shared_parent += len;
849
850 let mut multi_chunk_slice = !tail.is_empty();
853 let head_start = loop {
854 let mut stack_idx = node_stack.len() - 1;
855 let (_, child_i) = node_stack.last_mut().unwrap();
856
857 if *child_i == 0 {
860 while node_stack[stack_idx].1 == 0 {
863 debug_assert_ne!(stack_idx, 0, "iterated past the first leaf");
864 stack_idx -= 1;
865 }
866
867 if stack_idx < shared_parent {
870 for (node, child_i) in &node_stack[stack_idx..shared_parent] {
871 for &child_pos in &node.children().info()[..*child_i] {
872 pos_in_shared_parent += child_pos;
873 }
874 }
875 shared_parent = stack_idx;
876 }
877
878 node_stack[stack_idx].1 -= 1;
880 while stack_idx < (node_stack.len() - 1) {
881 let child_i = node_stack[stack_idx].1;
882 let node = &node_stack[stack_idx].0.children().nodes()[child_i];
883 node_stack[stack_idx + 1] = (node, node.child_count() - 1);
884 stack_idx += 1;
885 }
886 } else {
887 *child_i -= 1;
889 }
890
891 let (node, child_i) = *node_stack.last().unwrap();
892 let info = node.children().info()[child_i];
893 let available_bytes = *byte_idx;
894
895 if info.line_breaks != 0 {
896 *text = node.children().nodes()[child_i].leaf_text();
898 let mut line_start = last_line_start_byte_idx(text);
905 let line_len = text.len() - line_start;
907 if line_len >= available_bytes {
908 line_start = text.len() - available_bytes;
909 }
910 break line_start;
911 }
912
913 if info.bytes as usize >= available_bytes {
914 *text = node.children().nodes()[child_i].leaf_text();
917 break text.len() - *byte_idx;
918 }
919
920 len += info;
921 *byte_idx -= info.bytes as usize;
922 multi_chunk_slice = true;
923 };
924 let head = &text[head_start..];
925
926 *byte_idx -= head.len();
928 *leaf_byte_idx = head_start as u32;
929
930 let head_chars = count_chars(head) as Count;
934 let head_surrogates = count_utf16_surrogates(head) as Count;
935 let line = if multi_chunk_slice {
936 RSEnum::Full {
937 node: node_stack[shared_parent].0,
938 start_info: pos_in_shared_parent
939 - TextInfo {
940 bytes: head.len() as Count,
941 chars: head_chars,
942 utf16_surrogates: head_surrogates,
943 line_breaks: 0,
944 }
945 - len,
946 end_info: pos_in_shared_parent,
947 }
948 } else {
949 RSEnum::Light {
950 text: head,
951 char_count: head_chars,
952 utf16_surrogate_count: head_surrogates,
953 line_break_count: 0,
954 }
955 };
956 let line = RopeSlice(line);
957
958 Some(line)
959 }
960
961 Lines {
962 iter: LinesEnum::Light,
963 ref mut text,
964 ref mut byte_idx,
965 ref mut at_end,
966 ref mut line_idx,
967 ..
968 } => {
969 if std::mem::take(at_end) {
970 if text.is_empty() || ends_with_line_break(text) {
971 *line_idx -= 1;
972 return Some("".into());
973 }
974 } else if *byte_idx == 0 {
975 return None;
976 }
977
978 let end_idx = *byte_idx;
979 let start_idx = last_line_start_byte_idx(trim_line_break(&text[..end_idx]));
980 *byte_idx = start_idx;
981 *line_idx -= 1;
982 let line = &text[start_idx..end_idx];
983
984 return Some(RopeSlice(RSEnum::Light {
985 text: line,
986 char_count: count_chars(line) as Count,
987 utf16_surrogate_count: count_utf16_surrogates(line) as Count,
988 line_break_count: 1,
989 }));
990 }
991 }
992 }
993
994 fn next_impl(&mut self) -> Option<RopeSlice<'a>> {
995 match *self {
996 Lines {
997 iter:
998 LinesEnum::Full {
999 ref mut node_stack,
1000 ref mut leaf_byte_idx,
1001 total_bytes,
1002 },
1003 ref mut byte_idx,
1004 ref mut text,
1005 ref mut at_end,
1006 ref mut line_idx,
1007 ..
1008 } => {
1009 if *at_end {
1010 return None;
1011 } else if *byte_idx == total_bytes {
1012 *at_end = true;
1013 *line_idx += 1;
1014 return Some(RopeSlice(RSEnum::Light {
1015 text: "",
1016 char_count: 0,
1017 utf16_surrogate_count: 0,
1018 line_break_count: 0,
1019 }));
1020 }
1021 *line_idx += 1;
1022
1023 let head = &text[*leaf_byte_idx as usize..];
1024 let mut line_len = line_to_byte_idx(head, 1);
1025
1026 let available_bytes = total_bytes - *byte_idx;
1030 let (line_inside_chunk, line_break_count) = if line_len >= available_bytes {
1031 line_len = available_bytes;
1035 let ends_with_line_break = ends_with_line_break(&head[..line_len]);
1036 *at_end = !ends_with_line_break;
1037 (true, ends_with_line_break as u64)
1039 } else {
1040 (line_len != head.len() || ends_with_line_break(head), 1)
1045 };
1046
1047 if line_inside_chunk {
1049 let line = &head[..line_len];
1050 *byte_idx += line_len;
1051 *leaf_byte_idx += line_len as u32;
1052
1053 return Some(RopeSlice(RSEnum::Light {
1054 text: line,
1055 char_count: count_chars(line) as Count,
1056 utf16_surrogate_count: count_utf16_surrogates(line) as Count,
1057 line_break_count,
1058 }));
1059 }
1060
1061 *byte_idx += head.len();
1062
1063 let mut shared_parent = node_stack.len() - 1;
1069 let mut pos_in_shared_parent = {
1070 let (parent, child_i) = *node_stack.last().unwrap();
1071 parent.children().info()[..=child_i]
1072 .iter()
1073 .fold(TextInfo::new(), |res, it| res + *it)
1074 };
1075 let mut len = TextInfo::from_str(head);
1076 pos_in_shared_parent -= len;
1077
1078 let mut multi_chunk_slice = !head.is_empty();
1081 let (tail_len, tail_ends_with_newline) = loop {
1082 let mut stack_idx = node_stack.len() - 1;
1083
1084 let (_, child_i) = node_stack.last_mut().unwrap();
1086 *child_i += 1;
1087
1088 if *child_i >= node_stack[stack_idx].0.child_count() {
1091 while node_stack[stack_idx].1 >= (node_stack[stack_idx].0.child_count() - 1)
1094 {
1095 debug_assert_ne!(stack_idx, 0, "iterated past the last leaf");
1096 stack_idx -= 1;
1097 }
1098
1099 if stack_idx < shared_parent {
1102 for (node, child_i) in &node_stack[stack_idx..shared_parent] {
1103 for &child_pos in &node.children().info()[..*child_i] {
1104 pos_in_shared_parent += child_pos;
1105 }
1106 }
1107 shared_parent = stack_idx;
1108 }
1109
1110 node_stack[stack_idx].1 += 1;
1112 while stack_idx < (node_stack.len() - 1) {
1113 let child_i = node_stack[stack_idx].1;
1114 let node = &node_stack[stack_idx].0.children().nodes()[child_i];
1115 node_stack[stack_idx + 1] = (node, 0);
1116 stack_idx += 1;
1117 }
1118 }
1119
1120 let (node, child_i) = *node_stack.last().unwrap();
1121 let info = node.children().info()[child_i];
1122 let available_bytes = total_bytes - *byte_idx;
1123
1124 if info.line_breaks != 0 {
1125 *text = node.children().nodes()[child_i].leaf_text();
1127 let mut line_end = line_to_byte_idx(text, 1);
1129 let ends_with_newline = if line_end >= available_bytes {
1131 line_end = available_bytes;
1133 let ends_with_newline = ends_with_line_break(&text[..line_end]);
1134 *at_end = !ends_with_newline;
1135 ends_with_newline
1136 } else {
1137 true
1138 };
1139 break (line_end, ends_with_newline);
1140 }
1141
1142 if info.bytes as usize >= available_bytes {
1143 *at_end = true;
1146 *text = node.children().nodes()[child_i].leaf_text();
1147 break (available_bytes, false);
1148 }
1149
1150 len += info;
1151 *byte_idx += info.bytes as usize;
1152 multi_chunk_slice = true;
1153 };
1154
1155 *byte_idx += tail_len;
1157 *leaf_byte_idx = tail_len as u32;
1158
1159 let line_tail = &text[..tail_len];
1161 let line_tail_chars = count_chars(line_tail) as Count;
1162 let line_tail_surrogates = count_utf16_surrogates(line_tail) as Count;
1163 let line = if multi_chunk_slice {
1164 RSEnum::Full {
1165 node: node_stack[shared_parent].0,
1166 start_info: pos_in_shared_parent,
1167 end_info: pos_in_shared_parent
1168 + len
1169 + TextInfo {
1170 bytes: tail_len as Count,
1171 chars: line_tail_chars,
1172 utf16_surrogates: line_tail_surrogates,
1173 line_breaks: tail_ends_with_newline as Count,
1174 },
1175 }
1176 } else {
1177 RSEnum::Light {
1178 text: line_tail,
1179 char_count: line_tail_chars,
1180 utf16_surrogate_count: line_tail_surrogates,
1181 line_break_count: tail_ends_with_newline as Count,
1182 }
1183 };
1184
1185 Some(RopeSlice(line))
1186 }
1187
1188 Lines {
1189 iter: LinesEnum::Light,
1190 text,
1191 ref mut byte_idx,
1192 ref mut at_end,
1193 ref mut line_idx,
1194 ..
1195 } => {
1196 if *at_end {
1197 return None;
1198 } else if *byte_idx == text.len() {
1199 *at_end = true;
1200 *line_idx += 1;
1201 return Some("".into());
1202 }
1203
1204 let start_idx = *byte_idx;
1205 let end_idx = line_to_byte_idx(&text[start_idx..], 1) + start_idx;
1206 *byte_idx = end_idx;
1207 *line_idx += 1;
1208
1209 if end_idx == text.len() {
1210 *at_end = !ends_with_line_break(text);
1211 }
1212
1213 return Some((&text[start_idx..end_idx]).into());
1214 }
1215 }
1216 }
1217}
1218
1219impl<'a> Iterator for Lines<'a> {
1220 type Item = RopeSlice<'a>;
1221
1222 #[inline(always)]
1227 fn next(&mut self) -> Option<RopeSlice<'a>> {
1228 if self.is_reversed {
1229 self.prev_impl()
1230 } else {
1231 self.next_impl()
1232 }
1233 }
1234
1235 fn size_hint(&self) -> (usize, Option<usize>) {
1236 if self.is_reversed {
1237 (self.line_idx, Some(self.line_idx))
1238 } else {
1239 (
1240 self.total_lines - self.line_idx,
1241 Some(self.total_lines - self.line_idx),
1242 )
1243 }
1244 }
1245}
1246
1247impl ExactSizeIterator for Lines<'_> {}
1248
1249#[derive(Debug, Clone)]
1275pub struct Chunks<'a> {
1276 iter: ChunksEnum<'a>,
1277 is_reversed: bool,
1278}
1279
1280#[derive(Debug, Clone)]
1281enum ChunksEnum<'a> {
1282 Full {
1283 node_stack: Vec<(&'a Arc<Node>, usize)>, total_bytes: usize, byte_idx: isize, },
1287 Light {
1288 text: &'a str,
1289 is_end: bool,
1290 },
1291}
1292
1293impl<'a> Chunks<'a> {
1294 #[inline(always)]
1295 pub(crate) fn new(node: &Arc<Node>) -> Chunks {
1296 let info = node.text_info();
1297 Chunks::new_with_range_at_byte(
1298 node,
1299 0,
1300 (0, info.bytes as usize),
1301 (0, info.chars as usize),
1302 (0, info.line_breaks as usize + 1),
1303 )
1304 .0
1305 }
1306
1307 #[inline(always)]
1308 pub(crate) fn new_with_range(
1309 node: &Arc<Node>,
1310 byte_idx_range: (usize, usize),
1311 char_idx_range: (usize, usize),
1312 line_break_idx_range: (usize, usize),
1313 ) -> Chunks {
1314 Chunks::new_with_range_at_byte(
1315 node,
1316 byte_idx_range.0,
1317 byte_idx_range,
1318 char_idx_range,
1319 line_break_idx_range,
1320 )
1321 .0
1322 }
1323
1324 pub(crate) fn new_with_range_at_byte(
1340 node: &Arc<Node>,
1341 at_byte: usize,
1342 byte_idx_range: (usize, usize),
1343 char_idx_range: (usize, usize),
1344 line_break_idx_range: (usize, usize),
1345 ) -> (Chunks, usize, usize, usize) {
1346 debug_assert!(at_byte >= byte_idx_range.0);
1347 debug_assert!(at_byte <= byte_idx_range.1);
1348
1349 let start_byte = byte_idx_range.0;
1351 let end_byte = byte_idx_range.1;
1352
1353 if start_byte == end_byte {
1355 return (
1356 Chunks {
1357 iter: ChunksEnum::Light {
1358 text: "",
1359 is_end: false,
1360 },
1361 is_reversed: false,
1362 },
1363 0,
1364 0,
1365 0,
1366 );
1367 }
1368
1369 if node.is_leaf() {
1371 let text = &node.leaf_text()[start_byte..end_byte];
1372 if at_byte == end_byte {
1373 return (
1374 Chunks {
1375 iter: ChunksEnum::Light {
1376 text: text,
1377 is_end: true,
1378 },
1379 is_reversed: false,
1380 },
1381 text.len(),
1382 count_chars(text),
1383 byte_to_line_idx(text, text.len()),
1384 );
1385 } else {
1386 return (
1387 Chunks {
1388 iter: ChunksEnum::Light {
1389 text: text,
1390 is_end: false,
1391 },
1392 is_reversed: false,
1393 },
1394 0,
1395 0,
1396 0,
1397 );
1398 }
1399 }
1400
1401 let mut info = TextInfo::new();
1404 let mut byte_idx = at_byte as isize;
1405 let node_stack = {
1406 let mut node_stack: Vec<(&Arc<Node>, usize)> = Vec::new();
1407 let mut node_ref = node;
1408 loop {
1409 match **node_ref {
1410 Node::Leaf(ref text) => {
1411 if at_byte < end_byte || byte_idx == 0 {
1412 byte_idx = info.bytes as isize - start_byte as isize;
1413 } else {
1414 byte_idx =
1415 (info.bytes as isize + text.len() as isize) - start_byte as isize;
1416 info = TextInfo {
1417 bytes: byte_idx_range.1 as u64,
1418 chars: char_idx_range.1 as u64,
1419 utf16_surrogates: 0, line_breaks: line_break_idx_range.1 as u64 - 1,
1421 };
1422 (*node_stack.last_mut().unwrap()).1 += 1;
1423 }
1424 break;
1425 }
1426 Node::Internal(ref children) => {
1427 let (child_i, acc_info) = children.search_byte_idx(byte_idx as usize);
1428 info += acc_info;
1429 node_stack.push((node_ref, child_i));
1430 node_ref = &children.nodes()[child_i];
1431 byte_idx -= acc_info.bytes as isize;
1432 }
1433 }
1434 }
1435 node_stack
1436 };
1437
1438 (
1440 Chunks {
1441 iter: ChunksEnum::Full {
1442 node_stack: node_stack,
1443 total_bytes: end_byte - start_byte,
1444 byte_idx: byte_idx,
1445 },
1446 is_reversed: false,
1447 },
1448 (info.bytes as usize).max(byte_idx_range.0),
1449 (info.chars as usize).max(char_idx_range.0),
1450 (info.line_breaks as usize).max(line_break_idx_range.0),
1451 )
1452 }
1453
1454 #[inline(always)]
1455 pub(crate) fn new_with_range_at_char(
1456 node: &Arc<Node>,
1457 at_char: usize,
1458 byte_idx_range: (usize, usize),
1459 char_idx_range: (usize, usize),
1460 line_break_idx_range: (usize, usize),
1461 ) -> (Chunks, usize, usize, usize) {
1462 let at_byte = if at_char == char_idx_range.1 {
1463 byte_idx_range.1
1464 } else {
1465 (node.get_chunk_at_char(at_char).1.bytes as usize).max(byte_idx_range.0)
1466 };
1467
1468 Chunks::new_with_range_at_byte(
1469 node,
1470 at_byte,
1471 byte_idx_range,
1472 char_idx_range,
1473 line_break_idx_range,
1474 )
1475 }
1476
1477 #[inline(always)]
1478 pub(crate) fn new_with_range_at_line_break(
1479 node: &Arc<Node>,
1480 at_line_break: usize,
1481 byte_idx_range: (usize, usize),
1482 char_idx_range: (usize, usize),
1483 line_break_idx_range: (usize, usize),
1484 ) -> (Chunks, usize, usize, usize) {
1485 let at_byte = if at_line_break == line_break_idx_range.1 {
1486 byte_idx_range.1
1487 } else {
1488 (node.get_chunk_at_line_break(at_line_break).1.bytes as usize).max(byte_idx_range.0)
1489 };
1490
1491 Chunks::new_with_range_at_byte(
1492 node,
1493 at_byte,
1494 byte_idx_range,
1495 char_idx_range,
1496 line_break_idx_range,
1497 )
1498 }
1499
1500 pub(crate) fn from_str(text: &str, at_end: bool) -> Chunks {
1501 Chunks {
1502 iter: ChunksEnum::Light {
1503 text: text,
1504 is_end: at_end,
1505 },
1506 is_reversed: false,
1507 }
1508 }
1509
1510 #[inline]
1515 pub fn reverse(&mut self) {
1516 self.is_reversed = !self.is_reversed;
1517 }
1518
1519 #[inline]
1532 #[must_use]
1533 pub fn reversed(mut self) -> Chunks<'a> {
1534 self.reverse();
1535 self
1536 }
1537
1538 #[inline(always)]
1542 pub fn prev(&mut self) -> Option<&'a str> {
1543 if !self.is_reversed {
1544 self.prev_impl()
1545 } else {
1546 self.next_impl()
1547 }
1548 }
1549
1550 fn prev_impl(&mut self) -> Option<&'a str> {
1551 match *self {
1552 Chunks {
1553 iter:
1554 ChunksEnum::Full {
1555 ref mut node_stack,
1556 total_bytes,
1557 ref mut byte_idx,
1558 },
1559 ..
1560 } => {
1561 if *byte_idx <= 0 {
1562 return None;
1563 }
1564
1565 let mut stack_idx = node_stack.len() - 1;
1567 if node_stack[stack_idx].1 == 0 {
1568 while node_stack[stack_idx].1 == 0 {
1569 if stack_idx == 0 {
1570 return None;
1571 } else {
1572 stack_idx -= 1;
1573 }
1574 }
1575 node_stack[stack_idx].1 -= 1;
1576 while stack_idx < (node_stack.len() - 1) {
1577 let child_i = node_stack[stack_idx].1;
1578 let node = &node_stack[stack_idx].0.children().nodes()[child_i];
1579 node_stack[stack_idx + 1] = (node, node.child_count() - 1);
1580 stack_idx += 1;
1581 }
1582 node_stack[stack_idx].1 += 1;
1583 }
1584
1585 let (node, ref mut child_i) = node_stack.last_mut().unwrap();
1587 *child_i -= 1;
1588
1589 let text = node.children().nodes()[*child_i].leaf_text();
1591 *byte_idx -= text.len() as isize;
1592 let text_slice = {
1593 let start_byte = if *byte_idx < 0 {
1594 (-*byte_idx) as usize
1595 } else {
1596 0
1597 };
1598 let end_byte = text.len().min((total_bytes as isize - *byte_idx) as usize);
1599 &text[start_byte..end_byte]
1600 };
1601
1602 return Some(text_slice);
1604 }
1605
1606 Chunks {
1607 iter:
1608 ChunksEnum::Light {
1609 text,
1610 ref mut is_end,
1611 },
1612 ..
1613 } => {
1614 if !*is_end || text.is_empty() {
1615 return None;
1616 } else {
1617 *is_end = false;
1618 return Some(text);
1619 }
1620 }
1621 }
1622 }
1623
1624 fn next_impl(&mut self) -> Option<&'a str> {
1625 match *self {
1626 Chunks {
1627 iter:
1628 ChunksEnum::Full {
1629 ref mut node_stack,
1630 total_bytes,
1631 ref mut byte_idx,
1632 },
1633 ..
1634 } => {
1635 if *byte_idx >= total_bytes as isize {
1636 return None;
1637 }
1638
1639 let mut stack_idx = node_stack.len() - 1;
1641 if node_stack[stack_idx].1 >= node_stack[stack_idx].0.child_count() {
1642 while node_stack[stack_idx].1 >= (node_stack[stack_idx].0.child_count() - 1) {
1643 if stack_idx == 0 {
1644 return None;
1645 } else {
1646 stack_idx -= 1;
1647 }
1648 }
1649 node_stack[stack_idx].1 += 1;
1650 while stack_idx < (node_stack.len() - 1) {
1651 let child_i = node_stack[stack_idx].1;
1652 let node = &node_stack[stack_idx].0.children().nodes()[child_i];
1653 node_stack[stack_idx + 1] = (node, 0);
1654 stack_idx += 1;
1655 }
1656 }
1657
1658 let (node, ref mut child_i) = node_stack.last_mut().unwrap();
1660
1661 let text = node.children().nodes()[*child_i].leaf_text();
1663 let text_slice = {
1664 let start_byte = if *byte_idx < 0 {
1665 (-*byte_idx) as usize
1666 } else {
1667 0
1668 };
1669 let end_byte = text.len().min((total_bytes as isize - *byte_idx) as usize);
1670 &text[start_byte..end_byte]
1671 };
1672
1673 *byte_idx += text.len() as isize;
1675 *child_i += 1;
1676
1677 return Some(text_slice);
1679 }
1680
1681 Chunks {
1682 iter:
1683 ChunksEnum::Light {
1684 text,
1685 ref mut is_end,
1686 },
1687 ..
1688 } => {
1689 if *is_end || text.is_empty() {
1690 return None;
1691 } else {
1692 *is_end = true;
1693 return Some(text);
1694 }
1695 }
1696 }
1697 }
1698}
1699
1700impl<'a> Iterator for Chunks<'a> {
1701 type Item = &'a str;
1702
1703 #[inline(always)]
1707 fn next(&mut self) -> Option<&'a str> {
1708 if !self.is_reversed {
1709 self.next_impl()
1710 } else {
1711 self.prev_impl()
1712 }
1713 }
1714}
1715
1716#[cfg(test)]
1717mod tests {
1718 #![allow(clippy::while_let_on_iterator)]
1719 use super::*;
1720 use crate::Rope;
1721
1722 const TEXT: &str = "\r\n\
1723 Hello there! How're you doing? It's a fine day, \
1724 isn't it? Aren't you glad we're alive?\r\n\
1725 こんにちは!元気ですか?日はいいですね。\
1726 私たちが生きだって嬉しいではないか?\r\n\
1727 Hello there! How're you doing? It's a fine day, \
1728 isn't it? Aren't you glad we're alive?\r\n\
1729 こんにちは!元気ですか?日はいいですね。\
1730 私たちが生きだって嬉しいではないか?\r\n\
1731 Hello there! How're you doing? It's a fine day, \
1732 isn't it? Aren't you glad we're alive?\r\n\
1733 こんにちは!元気ですか?日はいいですね。\
1734 私たちが生きだって嬉しいではないか?\r\n\
1735 Hello there! How're you doing? It's a fine day, \
1736 isn't it? Aren't you glad we're alive?\r\n\
1737 こんにちは!元気ですか?日はいいですね。\
1738 私たちが生きだって嬉しいではないか?\r\n\
1739 Hello there! How're you doing? It's a fine day, \
1740 isn't it? Aren't you glad we're alive?\r\n\
1741 こんにちは!元気ですか?日はいいですね。\
1742 私たちが生きだって嬉しいではないか?\r\n\
1743 Hello there! How're you doing? It's a fine day, \
1744 isn't it? Aren't you glad we're alive?\r\n\
1745 こんにちは!元気ですか?日はいいですね。\
1746 私たちが生きだって嬉しいではないか?\r\n\
1747 Hello there! How're you doing? It's a fine day, \
1748 isn't it? Aren't you glad we're alive?\r\n\
1749 こんにちは!元気ですか?日はいいですね。\
1750 私たちが生きだって嬉しいではないか?\r\n\
1751 Hello there! How're you doing? It's a fine day, \
1752 isn't it? Aren't you glad we're alive?\r\n\
1753 こんにちは!元気ですか?日はいいですね。\
1754 私たちが生きだって嬉しいではないか?\r\n\
1755 Hello there! How're you doing? It's a fine day, \
1756 isn't it? Aren't you glad we're alive?\r\n\
1757 こんにちは!元気ですか?日はいいですね。\
1758 私たちが生きだって嬉しいではないか?\r\n\
1759 Hello there! How're you doing? It's a fine day, \
1760 isn't it? Aren't you glad we're alive?\r\n\
1761 こんにちは!元気ですか?日はいいですね。\
1762 私たちが生きだって嬉しいではないか?\r\n\
1763 Hello there! How're you doing? It's a fine day, \
1764 isn't it? Aren't you glad we're alive?\r\n\
1765 こんにちは!元気ですか?日はいいですね。\
1766 私たちが生きだって嬉しいではないか?\r\n\
1767 Hello there! How're you doing? It's a fine day, \
1768 isn't it? Aren't you glad we're alive?\r\n\
1769 こんにちは!元気ですか?日はいいですね。\
1770 私たちが生きだって嬉しいではないか?\r\n\
1771 Hello there! How're you doing? It's a fine day, \
1772 isn't it? Aren't you glad we're alive?\r\n\
1773 こんにちは!元気ですか?日はいいですね。\
1774 私たちが生きだって嬉しいではないか?\r\n\
1775 Hello there! How're you doing? It's a fine day, \
1776 isn't it? Aren't you glad we're alive?\r\n\
1777 こんにちは!元気ですか?日はいいですね。\
1778 私たちが生きだって嬉しいではないか?\r\n\
1779 Hello there! How're you doing? It's a fine day, \
1780 isn't it? Aren't you glad we're alive?\r\n\
1781 こんにちは!元気ですか?日はいいですね。\
1782 私たちが生きだって嬉しいではないか?\r\n\
1783 Hello there! How're you doing? It's a fine day, \
1784 isn't it? Aren't you glad we're alive?\r\n\
1785 こんにちは!元気ですか?日はいいですね。\
1786 私たちが生きだって嬉しいではないか?\r\n\
1787 ";
1788
1789 #[test]
1790 #[cfg_attr(miri, ignore)]
1791 fn bytes_01() {
1792 let r = Rope::from_str(TEXT);
1793 for (br, bt) in r.bytes().zip(TEXT.bytes()) {
1794 assert_eq!(br, bt);
1795 }
1796 }
1797
1798 #[test]
1799 #[cfg_attr(miri, ignore)]
1800 fn bytes_02() {
1801 let r = Rope::from_str(TEXT);
1802 let mut itr = r.bytes();
1803 while let Some(_) = itr.next() {}
1804
1805 let mut i = TEXT.len();
1806 while let Some(b) = itr.prev() {
1807 i -= 1;
1808 assert_eq!(b, TEXT.as_bytes()[i]);
1809 }
1810 }
1811
1812 #[test]
1813 #[cfg_attr(miri, ignore)]
1814 fn bytes_03() {
1815 let r = Rope::from_str(TEXT);
1816 let mut itr = r.bytes();
1817
1818 itr.next();
1819 itr.prev();
1820 assert_eq!(None, itr.prev());
1821 }
1822
1823 #[test]
1824 #[cfg_attr(miri, ignore)]
1825 fn bytes_04() {
1826 let r = Rope::from_str(TEXT);
1827 let mut itr = r.bytes();
1828 while let Some(_) = itr.next() {}
1829
1830 itr.prev();
1831 itr.next();
1832 assert_eq!(None, itr.next());
1833 }
1834
1835 #[test]
1836 #[cfg_attr(miri, ignore)]
1837 fn bytes_05() {
1838 let r = Rope::from_str(TEXT);
1839 let mut itr = r.bytes();
1840
1841 assert_eq!(None, itr.prev());
1842 itr.next();
1843 itr.prev();
1844 assert_eq!(None, itr.prev());
1845 }
1846
1847 #[test]
1848 #[cfg_attr(miri, ignore)]
1849 fn bytes_06() {
1850 let r = Rope::from_str(TEXT);
1851 let mut itr = r.bytes();
1852 while let Some(_) = itr.next() {}
1853
1854 assert_eq!(None, itr.next());
1855 itr.prev();
1856 itr.next();
1857 assert_eq!(None, itr.next());
1858 }
1859
1860 #[test]
1861 #[cfg_attr(miri, ignore)]
1862 fn bytes_07() {
1863 let mut itr = Bytes::from_str("a");
1864
1865 assert_eq!(Some(0x61), itr.next());
1866 assert_eq!(None, itr.next());
1867 assert_eq!(Some(0x61), itr.prev());
1868 assert_eq!(None, itr.prev());
1869 }
1870
1871 #[test]
1872 #[cfg_attr(miri, ignore)]
1873 fn bytes_at_01() {
1874 let r = Rope::from_str(TEXT);
1875
1876 let mut bytes_1 = TEXT.bytes();
1877 for i in 0..(r.len_bytes() + 1) {
1878 let mut bytes_2 = r.bytes_at(i);
1879 assert_eq!(bytes_1.next(), bytes_2.next());
1880 }
1881 }
1882
1883 #[test]
1884 #[cfg_attr(miri, ignore)]
1885 fn bytes_at_02() {
1886 let r = Rope::from_str(TEXT);
1887 let mut bytes = r.bytes_at(r.len_bytes());
1888 assert_eq!(bytes.next(), None);
1889 }
1890
1891 #[test]
1892 #[cfg_attr(miri, ignore)]
1893 fn bytes_at_03() {
1894 let r = Rope::from_str(TEXT);
1895 let mut bytes_1 = r.bytes_at(r.len_bytes());
1896 let mut bytes_2 = TEXT.bytes();
1897
1898 while let Some(b) = bytes_2.next_back() {
1899 assert_eq!(bytes_1.prev(), Some(b));
1900 }
1901 }
1902
1903 #[test]
1904 #[cfg_attr(miri, ignore)]
1905 fn bytes_exact_size_iter_01() {
1906 let r = Rope::from_str(TEXT);
1907 let s = r.slice(34..301);
1908
1909 let mut byte_count = s.len_bytes();
1910 let mut bytes = s.bytes();
1911
1912 assert_eq!(byte_count, bytes.len());
1913
1914 while let Some(_) = bytes.next() {
1915 byte_count -= 1;
1916 assert_eq!(byte_count, bytes.len());
1917 }
1918
1919 bytes.next();
1920 bytes.next();
1921 bytes.next();
1922 bytes.next();
1923 bytes.next();
1924 bytes.next();
1925 bytes.next();
1926 assert_eq!(bytes.len(), 0);
1927 assert_eq!(byte_count, 0);
1928 }
1929
1930 #[test]
1931 #[cfg_attr(miri, ignore)]
1932 fn bytes_exact_size_iter_02() {
1933 let r = Rope::from_str(TEXT);
1934 let s = r.slice(34..301);
1935
1936 for i in 0..=s.len_bytes() {
1937 let bytes = s.bytes_at(i);
1938 assert_eq!(s.len_bytes() - i, bytes.len());
1939 }
1940 }
1941
1942 #[test]
1943 #[cfg_attr(miri, ignore)]
1944 fn bytes_exact_size_iter_03() {
1945 let r = Rope::from_str(TEXT);
1946 let s = r.slice(34..301);
1947
1948 let mut byte_count = 0;
1949 let mut bytes = s.bytes_at(s.len_bytes());
1950
1951 assert_eq!(byte_count, bytes.len());
1952
1953 while bytes.prev().is_some() {
1954 byte_count += 1;
1955 assert_eq!(byte_count, bytes.len());
1956 }
1957
1958 assert_eq!(bytes.len(), s.len_bytes());
1959 bytes.prev();
1960 bytes.prev();
1961 bytes.prev();
1962 bytes.prev();
1963 bytes.prev();
1964 bytes.prev();
1965 bytes.prev();
1966 assert_eq!(bytes.len(), s.len_bytes());
1967 assert_eq!(byte_count, s.len_bytes());
1968 }
1969
1970 #[test]
1971 #[cfg_attr(miri, ignore)]
1972 fn bytes_reverse_01() {
1973 let r = Rope::from_str(TEXT);
1974 let mut itr = r.bytes();
1975 let mut stack = Vec::new();
1976
1977 for _ in 0..32 {
1978 stack.push(itr.next().unwrap());
1979 }
1980 itr.reverse();
1981 for _ in 0..32 {
1982 assert_eq!(stack.pop(), itr.next());
1983 }
1984 }
1985
1986 #[test]
1987 #[cfg_attr(miri, ignore)]
1988 fn bytes_reverse_02() {
1989 let r = Rope::from_str(TEXT);
1990 let mut itr = r.bytes_at(r.len_bytes() / 3);
1991 let mut stack = Vec::new();
1992
1993 for _ in 0..32 {
1994 stack.push(itr.next().unwrap());
1995 }
1996 itr.reverse();
1997 for _ in 0..32 {
1998 assert_eq!(stack.pop(), itr.next());
1999 }
2000 }
2001
2002 #[test]
2003 #[cfg_attr(miri, ignore)]
2004 fn bytes_reverse_03() {
2005 let r = Rope::from_str(TEXT);
2006 let mut itr = r.bytes_at(r.len_bytes() / 3);
2007 let mut stack = Vec::new();
2008
2009 itr.reverse();
2010 for _ in 0..32 {
2011 stack.push(itr.next().unwrap());
2012 }
2013 itr.reverse();
2014 for _ in 0..32 {
2015 assert_eq!(stack.pop(), itr.next());
2016 }
2017 }
2018
2019 #[test]
2020 #[cfg_attr(miri, ignore)]
2021 fn bytes_reverse_04() {
2022 let mut itr = Bytes::from_str("a");
2023
2024 assert_eq!(Some(0x61), itr.next());
2025 assert_eq!(None, itr.next());
2026 itr.reverse();
2027 assert_eq!(Some(0x61), itr.next());
2028 assert_eq!(None, itr.next());
2029 }
2030
2031 #[test]
2032 #[cfg_attr(miri, ignore)]
2033 fn bytes_reverse_exact_size_iter_01() {
2034 let r = Rope::from_str(TEXT);
2035 let s = r.slice(34..301);
2036
2037 let mut bytes = s.bytes_at(42);
2038 bytes.reverse();
2039 let mut byte_count = 42;
2040
2041 assert_eq!(42, bytes.len());
2042
2043 while let Some(_) = bytes.next() {
2044 byte_count -= 1;
2045 assert_eq!(byte_count, bytes.len());
2046 }
2047
2048 bytes.next();
2049 bytes.next();
2050 bytes.next();
2051 bytes.next();
2052 bytes.next();
2053 bytes.next();
2054 bytes.next();
2055 assert_eq!(bytes.len(), 0);
2056 assert_eq!(byte_count, 0);
2057 }
2058
2059 #[test]
2060 #[cfg_attr(miri, ignore)]
2061 fn chars_01() {
2062 let r = Rope::from_str(TEXT);
2063 for (cr, ct) in r.chars().zip(TEXT.chars()) {
2064 assert_eq!(cr, ct);
2065 }
2066 }
2067
2068 #[test]
2069 #[cfg_attr(miri, ignore)]
2070 fn chars_02() {
2071 let r = Rope::from_str(TEXT);
2072 let mut itr = r.chars();
2073 let mut text_itr = TEXT.chars();
2074 while let Some(_) = itr.next() {}
2075
2076 while let Some(b) = itr.prev() {
2077 assert_eq!(b, text_itr.next_back().unwrap());
2078 }
2079 }
2080
2081 #[test]
2082 #[cfg_attr(miri, ignore)]
2083 fn chars_03() {
2084 let r = Rope::from_str(TEXT);
2085 let mut itr = r.chars();
2086
2087 itr.next();
2088 itr.prev();
2089 assert_eq!(None, itr.prev());
2090 }
2091
2092 #[test]
2093 #[cfg_attr(miri, ignore)]
2094 fn chars_04() {
2095 let r = Rope::from_str(TEXT);
2096 let mut itr = r.chars();
2097 while let Some(_) = itr.next() {}
2098
2099 itr.prev();
2100 itr.next();
2101 assert_eq!(None, itr.next());
2102 }
2103
2104 #[test]
2105 #[cfg_attr(miri, ignore)]
2106 fn chars_05() {
2107 let r = Rope::from_str(TEXT);
2108 let mut itr = r.chars();
2109
2110 assert_eq!(None, itr.prev());
2111 itr.next();
2112 itr.prev();
2113 assert_eq!(None, itr.prev());
2114 }
2115
2116 #[test]
2117 #[cfg_attr(miri, ignore)]
2118 fn chars_06() {
2119 let r = Rope::from_str(TEXT);
2120 let mut itr = r.chars();
2121 while let Some(_) = itr.next() {}
2122
2123 assert_eq!(None, itr.next());
2124 itr.prev();
2125 itr.next();
2126 assert_eq!(None, itr.next());
2127 }
2128
2129 #[test]
2130 #[cfg_attr(miri, ignore)]
2131 fn chars_07() {
2132 let mut itr = Chars::from_str("a");
2133
2134 assert_eq!(Some('a'), itr.next());
2135 assert_eq!(None, itr.next());
2136 assert_eq!(Some('a'), itr.prev());
2137 assert_eq!(None, itr.prev());
2138 }
2139
2140 #[test]
2141 #[cfg_attr(miri, ignore)]
2142 fn chars_at_01() {
2143 let r = Rope::from_str(TEXT);
2144
2145 let mut chars_1 = TEXT.chars();
2146 for i in 0..(r.len_chars() + 1) {
2147 let mut chars_2 = r.chars_at(i);
2148 assert_eq!(chars_1.next(), chars_2.next());
2149 }
2150 }
2151
2152 #[test]
2153 #[cfg_attr(miri, ignore)]
2154 fn chars_at_02() {
2155 let r = Rope::from_str(TEXT);
2156 let mut chars = r.chars_at(r.len_chars());
2157 assert_eq!(chars.next(), None);
2158 }
2159
2160 #[test]
2161 #[cfg_attr(miri, ignore)]
2162 fn chars_at_03() {
2163 let r = Rope::from_str(TEXT);
2164 let mut chars_1 = r.chars_at(r.len_chars());
2165 let mut chars_2 = TEXT.chars();
2166
2167 while let Some(c) = chars_2.next_back() {
2168 assert_eq!(chars_1.prev(), Some(c));
2169 }
2170 }
2171
2172 #[test]
2173 #[cfg_attr(miri, ignore)]
2174 fn chars_exact_size_iter_01() {
2175 let r = Rope::from_str(TEXT);
2176 let s = r.slice(34..301);
2177
2178 let mut char_count = s.len_chars();
2179 let mut chars = s.chars();
2180
2181 assert_eq!(char_count, chars.len());
2182
2183 while let Some(_) = chars.next() {
2184 char_count -= 1;
2185 assert_eq!(char_count, chars.len());
2186 }
2187
2188 assert_eq!(char_count, 0);
2189 assert_eq!(chars.len(), 0);
2190 }
2191
2192 #[test]
2193 #[cfg_attr(miri, ignore)]
2194 fn chars_exact_size_iter_02() {
2195 let r = Rope::from_str(TEXT);
2196 let s = r.slice(34..301);
2197
2198 for i in 0..=s.len_chars() {
2199 let chars = s.chars_at(i);
2200 assert_eq!(s.len_chars() - i, chars.len());
2201 }
2202 }
2203
2204 #[test]
2205 #[cfg_attr(miri, ignore)]
2206 fn chars_exact_size_iter_03() {
2207 let r = Rope::from_str(TEXT);
2208 let s = r.slice(34..301);
2209
2210 let mut char_count = 0;
2211 let mut chars = s.chars_at(s.len_chars());
2212
2213 assert_eq!(char_count, chars.len());
2214
2215 while chars.prev().is_some() {
2216 char_count += 1;
2217 assert_eq!(char_count, chars.len());
2218 }
2219
2220 assert_eq!(char_count, s.len_chars());
2221 assert_eq!(chars.len(), s.len_chars());
2222 chars.prev();
2223 assert_eq!(chars.len(), s.len_chars());
2224 }
2225
2226 #[test]
2227 #[cfg_attr(miri, ignore)]
2228 fn chars_reverse_01() {
2229 let r = Rope::from_str(TEXT);
2230 let mut itr = r.chars();
2231 let mut stack = Vec::new();
2232
2233 for _ in 0..32 {
2234 stack.push(itr.next().unwrap());
2235 }
2236 itr.reverse();
2237 for _ in 0..32 {
2238 assert_eq!(stack.pop(), itr.next());
2239 }
2240 }
2241
2242 #[test]
2243 #[cfg_attr(miri, ignore)]
2244 fn chars_reverse_02() {
2245 let r = Rope::from_str(TEXT);
2246 let mut itr = r.chars_at(r.len_chars() / 3);
2247 let mut stack = Vec::new();
2248
2249 for _ in 0..32 {
2250 stack.push(itr.next().unwrap());
2251 }
2252 itr.reverse();
2253 for _ in 0..32 {
2254 assert_eq!(stack.pop(), itr.next());
2255 }
2256 }
2257
2258 #[test]
2259 #[cfg_attr(miri, ignore)]
2260 fn chars_reverse_03() {
2261 let r = Rope::from_str(TEXT);
2262 let mut itr = r.chars_at(r.len_chars() / 3);
2263 let mut stack = Vec::new();
2264
2265 itr.reverse();
2266 for _ in 0..32 {
2267 stack.push(itr.next().unwrap());
2268 }
2269 itr.reverse();
2270 for _ in 0..32 {
2271 assert_eq!(stack.pop(), itr.next());
2272 }
2273 }
2274
2275 #[test]
2276 #[cfg_attr(miri, ignore)]
2277 fn chars_reverse_04() {
2278 let mut itr = Chars::from_str("a");
2279
2280 assert_eq!(Some('a'), itr.next());
2281 assert_eq!(None, itr.next());
2282 itr.reverse();
2283 assert_eq!(Some('a'), itr.next());
2284 assert_eq!(None, itr.next());
2285 }
2286
2287 #[test]
2288 #[cfg_attr(miri, ignore)]
2289 fn chars_reverse_exact_size_iter_01() {
2290 let r = Rope::from_str(TEXT);
2291 let s = r.slice(34..301);
2292
2293 let mut chars = s.chars_at(42);
2294 chars.reverse();
2295 let mut char_count = 42;
2296
2297 assert_eq!(42, chars.len());
2298
2299 while let Some(_) = chars.next() {
2300 char_count -= 1;
2301 assert_eq!(char_count, chars.len());
2302 }
2303
2304 chars.next();
2305 chars.next();
2306 chars.next();
2307 chars.next();
2308 chars.next();
2309 chars.next();
2310 chars.next();
2311 assert_eq!(chars.len(), 0);
2312 assert_eq!(char_count, 0);
2313 }
2314
2315 #[test]
2316 #[cfg_attr(miri, ignore)]
2317 fn lines_21() {
2318 let r = Rope::from_str("a\nb\nc\nd\ne\nf\ng\nh\n");
2319 for (line, c) in r.lines().zip('a'..='h') {
2320 assert_eq!(line, format!("{c}\n"))
2321 }
2322 for (line, c) in r
2323 .lines_at(r.len_lines() - 1)
2324 .reversed()
2325 .zip(('a'..='h').rev())
2326 {
2327 assert_eq!(line, format!("{c}\n"))
2328 }
2329
2330 let r = Rope::from_str("ab\nc\nd\ne\nf\ng\nh\n");
2331 for (line, c) in r.slice(1..).lines().zip('b'..='h') {
2332 assert_eq!(line, format!("{c}\n"))
2333 }
2334 }
2335
2336 #[test]
2337 #[cfg_attr(miri, ignore)]
2338 fn lines_01() {
2339 let r = Rope::from_str(TEXT);
2340 let s = r.slice(..);
2341
2342 assert_eq!(34, r.lines().count());
2343 assert_eq!(34, s.lines().count());
2344
2345 let mut lines = r.lines();
2347 assert_eq!("\r\n", lines.next().unwrap());
2348 for _ in 0..16 {
2349 assert_eq!(
2350 "Hello there! How're you doing? It's a fine day, \
2351 isn't it? Aren't you glad we're alive?\r\n",
2352 lines.next().unwrap()
2353 );
2354 assert_eq!(
2355 "こんにちは!元気ですか?日はいいですね。\
2356 私たちが生きだって嬉しいではないか?\r\n",
2357 lines.next().unwrap()
2358 );
2359 }
2360 assert_eq!("", lines.next().unwrap());
2361 assert!(lines.next().is_none());
2362
2363 let mut lines = s.lines();
2365 assert_eq!("\r\n", lines.next().unwrap());
2366 for _ in 0..16 {
2367 assert_eq!(
2368 "Hello there! How're you doing? It's a fine day, \
2369 isn't it? Aren't you glad we're alive?\r\n",
2370 lines.next().unwrap()
2371 );
2372 assert_eq!(
2373 "こんにちは!元気ですか?日はいいですね。\
2374 私たちが生きだって嬉しいではないか?\r\n",
2375 lines.next().unwrap()
2376 );
2377 }
2378 assert_eq!("", lines.next().unwrap());
2379 assert!(lines.next().is_none());
2380 }
2381
2382 #[test]
2383 #[cfg_attr(miri, ignore)]
2384 fn lines_02() {
2385 let text = "Hello there!\nHow goes it?";
2386 let r = Rope::from_str(text);
2387 let s = r.slice(..);
2388
2389 assert_eq!(2, r.lines().count());
2390 assert_eq!(2, s.lines().count());
2391
2392 let mut lines = r.lines();
2393 assert_eq!("Hello there!\n", lines.next().unwrap());
2394 assert_eq!("How goes it?", lines.next().unwrap());
2395 assert!(lines.next().is_none());
2396
2397 let mut lines = s.lines();
2398 assert_eq!("Hello there!\n", lines.next().unwrap());
2399 assert_eq!("How goes it?", lines.next().unwrap());
2400 assert!(lines.next().is_none());
2401 }
2402
2403 #[test]
2404 #[cfg_attr(miri, ignore)]
2405 fn lines_03() {
2406 let text = "Hello there!\nHow goes it?\n";
2407 let r = Rope::from_str(text);
2408 let s = r.slice(..);
2409
2410 assert_eq!(3, r.lines().count());
2411 assert_eq!(3, s.lines().count());
2412
2413 let mut lines = r.lines();
2414 assert_eq!("Hello there!\n", lines.next().unwrap());
2415 assert_eq!("How goes it?\n", lines.next().unwrap());
2416 assert_eq!("", lines.next().unwrap());
2417 assert!(lines.next().is_none());
2418
2419 let mut lines = s.lines();
2420 assert_eq!("Hello there!\n", lines.next().unwrap());
2421 assert_eq!("How goes it?\n", lines.next().unwrap());
2422 assert_eq!("", lines.next().unwrap());
2423 assert!(lines.next().is_none());
2424 }
2425
2426 #[test]
2427 #[cfg_attr(miri, ignore)]
2428 fn lines_04() {
2429 let text = "Hello there!\nHow goes it?\nYeah!";
2430 let r = Rope::from_str(text);
2431 let s1 = r.slice(..25);
2432 let s2 = r.slice(..26);
2433
2434 assert_eq!(2, s1.lines().count());
2435 assert_eq!(3, s2.lines().count());
2436
2437 let mut lines = s1.lines();
2438 assert_eq!("Hello there!\n", lines.next().unwrap());
2439 assert_eq!("How goes it?", lines.next().unwrap());
2440 assert!(lines.next().is_none());
2441
2442 let mut lines = s2.lines();
2443 assert_eq!("Hello there!\n", lines.next().unwrap());
2444 assert_eq!("How goes it?\n", lines.next().unwrap());
2445 assert_eq!("", lines.next().unwrap());
2446 assert!(lines.next().is_none());
2447 }
2448
2449 #[test]
2450 #[cfg_attr(miri, ignore)]
2451 fn lines_05() {
2452 let text = "";
2453 let r = Rope::from_str(text);
2454 let s = r.slice(..);
2455
2456 assert_eq!(1, r.lines().count());
2457 assert_eq!(1, s.lines().count());
2458
2459 let mut lines = r.lines();
2460 assert_eq!("", lines.next().unwrap());
2461 assert!(lines.next().is_none());
2462
2463 let mut lines = s.lines();
2464 assert_eq!("", lines.next().unwrap());
2465 assert!(lines.next().is_none());
2466 }
2467
2468 #[test]
2469 #[cfg_attr(miri, ignore)]
2470 fn lines_06() {
2471 let text = "a";
2472 let r = Rope::from_str(text);
2473 let s = r.slice(..);
2474
2475 assert_eq!(1, r.lines().count());
2476 assert_eq!(1, s.lines().count());
2477
2478 let mut lines = r.lines();
2479 assert_eq!("a", lines.next().unwrap());
2480 assert!(lines.next().is_none());
2481
2482 let mut lines = s.lines();
2483 assert_eq!("a", lines.next().unwrap());
2484 assert!(lines.next().is_none());
2485 }
2486
2487 #[test]
2488 #[cfg_attr(miri, ignore)]
2489 fn lines_07() {
2490 let text = "a\nb";
2491 let r = Rope::from_str(text);
2492 let s = r.slice(..);
2493
2494 assert_eq!(2, r.lines().count());
2495 assert_eq!(2, s.lines().count());
2496
2497 let mut lines = r.lines();
2498 assert_eq!("a\n", lines.next().unwrap());
2499 assert_eq!("b", lines.next().unwrap());
2500 assert!(lines.next().is_none());
2501
2502 let mut lines = s.lines();
2503 assert_eq!("a\n", lines.next().unwrap());
2504 assert_eq!("b", lines.next().unwrap());
2505 assert!(lines.next().is_none());
2506 }
2507
2508 #[test]
2509 #[cfg_attr(miri, ignore)]
2510 fn lines_08() {
2511 let text = "\n";
2512 let r = Rope::from_str(text);
2513 let s = r.slice(..);
2514
2515 assert_eq!(2, r.lines().count());
2516 assert_eq!(2, s.lines().count());
2517
2518 let mut lines = r.lines();
2519 assert_eq!("\n", lines.next().unwrap());
2520 assert_eq!("", lines.next().unwrap());
2521 assert!(lines.next().is_none());
2522
2523 let mut lines = s.lines();
2524 assert_eq!("\n", lines.next().unwrap());
2525 assert_eq!("", lines.next().unwrap());
2526 assert!(lines.next().is_none());
2527 }
2528
2529 #[test]
2530 #[cfg_attr(miri, ignore)]
2531 fn lines_09() {
2532 let text = "a\nb\n";
2533 let r = Rope::from_str(text);
2534 let s = r.slice(..);
2535
2536 assert_eq!(3, r.lines().count());
2537 assert_eq!(3, s.lines().count());
2538
2539 let mut lines = r.lines();
2540 assert_eq!("a\n", lines.next().unwrap());
2541 assert_eq!("b\n", lines.next().unwrap());
2542 assert_eq!("", lines.next().unwrap());
2543 assert!(lines.next().is_none());
2544
2545 let mut lines = s.lines();
2546 assert_eq!("a\n", lines.next().unwrap());
2547 assert_eq!("b\n", lines.next().unwrap());
2548 assert_eq!("", lines.next().unwrap());
2549 assert!(lines.next().is_none());
2550 }
2551
2552 #[test]
2553 #[cfg_attr(miri, ignore)]
2554 fn lines_10() {
2555 let r = Rope::from_str(TEXT);
2556
2557 let mut itr = r.lines();
2558
2559 assert_eq!(None, itr.prev());
2560 assert_eq!(None, itr.prev());
2561 }
2562
2563 #[test]
2564 #[cfg_attr(miri, ignore)]
2565 fn lines_11() {
2566 let r = Rope::from_str(TEXT);
2567
2568 let mut lines = Vec::new();
2569 let mut itr = r.lines();
2570
2571 while let Some(line) = itr.next() {
2572 lines.push(line);
2573 }
2574
2575 while let Some(line) = itr.prev() {
2576 assert_eq!(line, lines.pop().unwrap());
2577 }
2578
2579 assert!(lines.is_empty());
2580 }
2581
2582 #[test]
2583 #[cfg_attr(miri, ignore)]
2584 fn lines_12() {
2585 let r = Rope::from_str(TEXT);
2586 let s = r.slice(34..301);
2587
2588 let mut lines = Vec::new();
2589 let mut itr = s.lines();
2590
2591 while let Some(line) = itr.next() {
2592 lines.push(line);
2593 }
2594
2595 while let Some(line) = itr.prev() {
2596 assert_eq!(line, lines.pop().unwrap());
2597 }
2598
2599 assert!(lines.is_empty());
2600 }
2601
2602 #[test]
2603 #[cfg_attr(miri, ignore)]
2604 fn lines_13() {
2605 let text = "";
2606 let r = Rope::from_str(text);
2607 let s = r.slice(..);
2608
2609 let mut lines = Vec::new();
2610 let mut itr = s.lines();
2611
2612 while let Some(text) = itr.next() {
2613 lines.push(text);
2614 }
2615
2616 while let Some(text) = itr.prev() {
2617 assert_eq!(text, lines.pop().unwrap());
2618 }
2619
2620 assert!(lines.is_empty());
2621 }
2622
2623 #[test]
2624 #[cfg_attr(miri, ignore)]
2625 fn lines_14() {
2626 let text = "a";
2627 let r = Rope::from_str(text);
2628 let s = r.slice(..);
2629
2630 let mut lines = Vec::new();
2631 let mut itr = s.lines();
2632
2633 while let Some(text) = itr.next() {
2634 lines.push(text);
2635 }
2636
2637 while let Some(text) = itr.prev() {
2638 assert_eq!(text, lines.pop().unwrap());
2639 }
2640
2641 assert!(lines.is_empty());
2642 }
2643
2644 #[test]
2645 #[cfg_attr(miri, ignore)]
2646 fn lines_15() {
2647 let text = "a\nb";
2648 let r = Rope::from_str(text);
2649 let s = r.slice(..);
2650
2651 let mut lines = Vec::new();
2652 let mut itr = s.lines();
2653
2654 while let Some(text) = itr.next() {
2655 lines.push(text);
2656 }
2657
2658 while let Some(text) = itr.prev() {
2659 assert_eq!(text, lines.pop().unwrap());
2660 }
2661
2662 assert!(lines.is_empty());
2663 }
2664
2665 #[test]
2666 #[cfg_attr(miri, ignore)]
2667 fn lines_16() {
2668 let text = "\n";
2669 let r = Rope::from_str(text);
2670 let s = r.slice(..);
2671
2672 let mut lines = Vec::new();
2673 let mut itr = s.lines();
2674
2675 while let Some(text) = itr.next() {
2676 lines.push(text);
2677 }
2678
2679 while let Some(text) = itr.prev() {
2680 assert_eq!(text, lines.pop().unwrap());
2681 }
2682
2683 assert!(lines.is_empty());
2684 }
2685
2686 #[test]
2687 #[cfg_attr(miri, ignore)]
2688 fn lines_17() {
2689 let text = "a\nb\n";
2690 let r = Rope::from_str(text);
2691 let s = r.slice(..);
2692
2693 let mut lines = Vec::new();
2694 let mut itr = s.lines();
2695
2696 while let Some(text) = itr.next() {
2697 lines.push(text);
2698 }
2699
2700 while let Some(text) = itr.prev() {
2701 assert_eq!(text, lines.pop().unwrap());
2702 }
2703
2704 assert!(lines.is_empty());
2705 }
2706
2707 #[test]
2708 #[cfg_attr(miri, ignore)]
2709 fn lines_at_01() {
2710 let r = Rope::from_str(TEXT);
2711
2712 for i in 0..r.len_lines() {
2713 let line = r.line(i);
2714 let mut lines = r.lines_at(i);
2715 assert_eq!(Some(line), lines.next());
2716 }
2717
2718 let mut lines = r.lines_at(r.len_lines());
2719 assert_eq!(None, lines.next());
2720 }
2721
2722 #[test]
2723 #[cfg_attr(miri, ignore)]
2724 fn lines_at_02() {
2725 let r = Rope::from_str(TEXT);
2726 let s = r.slice(34..301);
2727
2728 for i in 0..s.len_lines() {
2729 let line = s.line(i);
2730 let mut lines = s.lines_at(i);
2731 assert_eq!(Some(line), lines.next());
2732 }
2733
2734 let mut lines = s.lines_at(s.len_lines());
2735 assert_eq!(None, lines.next());
2736 }
2737
2738 #[test]
2739 #[cfg_attr(miri, ignore)]
2740 fn lines_at_03() {
2741 let r = Rope::from_str(TEXT);
2742 let s = r.slice(34..34);
2743
2744 let mut lines = s.lines_at(0);
2745 assert_eq!("", lines.next().unwrap());
2746
2747 let mut lines = s.lines_at(1);
2748 assert_eq!(None, lines.next());
2749 }
2750
2751 #[test]
2752 #[cfg_attr(miri, ignore)]
2753 fn lines_exact_size_iter_01() {
2754 let r = Rope::from_str(TEXT);
2755 let s = r.slice(34..301);
2756
2757 let mut line_count = s.len_lines();
2758 let mut lines = s.lines();
2759
2760 assert_eq!(line_count, lines.len());
2761
2762 while let Some(_) = lines.next() {
2763 line_count -= 1;
2764 assert_eq!(line_count, lines.len());
2765 }
2766
2767 assert_eq!(lines.len(), 0);
2768 lines.next();
2769 lines.next();
2770 lines.next();
2771 lines.next();
2772 lines.next();
2773 lines.next();
2774 lines.next();
2775 assert_eq!(lines.len(), 0);
2776 assert_eq!(line_count, 0);
2777 }
2778
2779 #[test]
2780 #[cfg_attr(miri, ignore)]
2781 fn lines_exact_size_iter_02() {
2782 let r = Rope::from_str(TEXT);
2783 let s = r.slice(34..301);
2784
2785 for i in 0..=s.len_lines() {
2786 let lines = s.lines_at(i);
2787 assert_eq!(s.len_lines() - i, lines.len());
2788 }
2789 }
2790
2791 #[test]
2792 #[cfg_attr(miri, ignore)]
2793 fn lines_exact_size_iter_03() {
2794 let r = Rope::from_str(TEXT);
2795 let s = r.slice(34..301);
2796
2797 let mut line_count = 0;
2798 let mut lines = s.lines_at(s.len_lines());
2799
2800 assert_eq!(line_count, lines.len());
2801
2802 while lines.prev().is_some() {
2803 line_count += 1;
2804 assert_eq!(line_count, lines.len());
2805 }
2806
2807 assert_eq!(lines.len(), s.len_lines());
2808 lines.prev();
2809 lines.prev();
2810 lines.prev();
2811 lines.prev();
2812 lines.prev();
2813 lines.prev();
2814 lines.prev();
2815 assert_eq!(lines.len(), s.len_lines());
2816 assert_eq!(line_count, s.len_lines());
2817 }
2818
2819 #[test]
2820 #[cfg_attr(miri, ignore)]
2821 fn lines_exact_size_iter_04() {
2822 let r = Rope::from_str("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
2824 for i in 0..r.len_chars() {
2825 let s = r.slice(..i);
2826 let lines = s.lines();
2827 if cfg!(any(feature = "cr_lines", feature = "unicode_lines")) {
2828 assert_eq!(lines.len(), 1 + ((i + 1) / 2));
2829 } else {
2830 assert_eq!(lines.len(), 1 + (i / 2));
2831 }
2832 assert_eq!(lines.len(), lines.count());
2833 }
2834 }
2835
2836 #[test]
2837 #[cfg_attr(miri, ignore)]
2838 fn lines_reverse_01() {
2839 let r = Rope::from_str(TEXT);
2840 let mut itr = r.lines();
2841 let mut stack = Vec::new();
2842
2843 for _ in 0..8 {
2844 stack.push(itr.next().unwrap());
2845 }
2846 itr.reverse();
2847 for _ in 0..8 {
2848 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
2849 }
2850 }
2851
2852 #[test]
2853 #[cfg_attr(miri, ignore)]
2854 fn lines_reverse_02() {
2855 let r = Rope::from_str(TEXT);
2856 let mut itr = r.lines_at(r.len_lines() / 3);
2857 let mut stack = Vec::new();
2858
2859 for _ in 0..8 {
2860 stack.push(itr.next().unwrap());
2861 }
2862 itr.reverse();
2863 for _ in 0..8 {
2864 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
2865 }
2866 }
2867
2868 #[test]
2869 #[cfg_attr(miri, ignore)]
2870 fn lines_reverse_03() {
2871 let r = Rope::from_str(TEXT);
2872 let mut itr = r.lines_at(r.len_lines() / 3);
2873 let mut stack = Vec::new();
2874
2875 itr.reverse();
2876 for _ in 0..8 {
2877 stack.push(itr.next().unwrap());
2878 }
2879 itr.reverse();
2880 for _ in 0..8 {
2881 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
2882 }
2883 }
2884
2885 #[test]
2886 #[cfg_attr(miri, ignore)]
2887 fn lines_reverse_04() {
2888 let mut itr = Lines::from_str("a\n", 1);
2889
2890 assert_eq!(Some("a\n".into()), itr.next());
2891 assert_eq!(Some("".into()), itr.next());
2892 assert_eq!(None, itr.next());
2893 itr.reverse();
2894 assert_eq!(Some("".into()), itr.next());
2895 assert_eq!(Some("a\n".into()), itr.next());
2896 assert_eq!(None, itr.next());
2897 }
2898
2899 #[test]
2900 #[cfg_attr(miri, ignore)]
2901 fn lines_reverse_exact_size_iter_01() {
2902 let r = Rope::from_str(TEXT);
2903 let s = r.slice(34..301);
2904
2905 let mut lines = s.lines_at(4);
2906 lines.reverse();
2907 let mut line_count = 4;
2908
2909 assert_eq!(4, lines.len());
2910
2911 while let Some(_) = lines.next() {
2912 line_count -= 1;
2913 assert_eq!(line_count, lines.len());
2914 }
2915
2916 lines.next();
2917 lines.next();
2918 lines.next();
2919 lines.next();
2920 lines.next();
2921 lines.next();
2922 lines.next();
2923 assert_eq!(lines.len(), 0);
2924 assert_eq!(line_count, 0);
2925 }
2926
2927 #[test]
2928 #[cfg_attr(miri, ignore)]
2929 fn lines_reverse_exact_size_iter_02() {
2930 let r = Rope::from_str("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
2932 for i in 0..r.len_chars() {
2933 let s = r.slice(..i);
2934 let lines = s.lines_at((i + 1) / 2).reversed();
2935 assert_eq!(lines.len(), lines.count());
2936 }
2937 }
2938
2939 #[test]
2940 #[cfg_attr(miri, ignore)]
2941 fn chunks_01() {
2942 let r = Rope::from_str(TEXT);
2943
2944 let mut idx = 0;
2945 for chunk in r.chunks() {
2946 assert_eq!(chunk, &TEXT[idx..(idx + chunk.len())]);
2947 idx += chunk.len();
2948 }
2949 }
2950
2951 #[test]
2952 #[cfg_attr(miri, ignore)]
2953 fn chunks_02() {
2954 let r = Rope::from_str("");
2955 let mut itr = r.chunks();
2956
2957 assert_eq!(None, itr.next());
2958 }
2959
2960 #[test]
2961 #[cfg_attr(miri, ignore)]
2962 fn chunks_03() {
2963 let r = Rope::from_str(TEXT);
2964
2965 let mut itr = r.chunks();
2966
2967 assert_eq!(None, itr.prev());
2968 }
2969
2970 #[test]
2971 #[cfg_attr(miri, ignore)]
2972 fn chunks_04() {
2973 let r = Rope::from_str(TEXT);
2974
2975 let mut chunks = Vec::new();
2976 let mut itr = r.chunks();
2977
2978 while let Some(text) = itr.next() {
2979 chunks.push(text);
2980 }
2981
2982 while let Some(text) = itr.prev() {
2983 assert_eq!(text, chunks.pop().unwrap());
2984 }
2985
2986 assert!(chunks.is_empty());
2987 }
2988
2989 #[test]
2990 #[cfg_attr(miri, ignore)]
2991 fn chunks_at_byte_01() {
2992 let r = Rope::from_str(TEXT);
2993
2994 for i in 0..r.len_bytes() {
2995 let (chunk, b, c, l) = r.chunk_at_byte(i);
2996 let (mut chunks, bs, cs, ls) = r.chunks_at_byte(i);
2997
2998 assert_eq!(b, bs);
2999 assert_eq!(c, cs);
3000 assert_eq!(l, ls);
3001 assert_eq!(Some(chunk), chunks.next());
3002 }
3003 }
3004
3005 #[test]
3006 #[cfg_attr(miri, ignore)]
3007 fn chunks_at_byte_02() {
3008 let r = Rope::from_str(TEXT);
3009 let s = r.slice(34..301);
3010
3011 for i in 0..(s.len_chars() + 1) {
3012 let (chunk, b, c, l) = s.chunk_at_byte(i);
3013 let (mut chunks, bs, cs, ls) = s.chunks_at_byte(i);
3014
3015 assert_eq!(b, bs);
3016 assert_eq!(c, cs);
3017 assert_eq!(l, ls);
3018 assert_eq!(Some(chunk), chunks.next());
3019 }
3020 }
3021
3022 #[test]
3023 #[cfg_attr(miri, ignore)]
3024 fn chunks_at_byte_03() {
3025 let r = Rope::from_str(TEXT);
3026 let s = r.slice(34..301);
3027
3028 let (mut chunks, _, _, _) = s.chunks_at_byte(s.len_bytes());
3029 assert_eq!(chunks.next(), None);
3030
3031 let (mut chunks, _, _, _) = s.chunks_at_byte(s.len_bytes());
3032 assert_eq!(s.chunks().last(), chunks.prev());
3033 }
3034
3035 #[test]
3036 #[cfg_attr(miri, ignore)]
3037 fn chunks_at_byte_04() {
3038 let r = Rope::from_str(TEXT);
3039 let s = r.slice(34..34);
3040
3041 let (mut chunks, _, _, _) = s.chunks_at_byte(0);
3042 assert_eq!(chunks.next(), None);
3043
3044 let (mut chunks, _, _, _) = s.chunks_at_byte(0);
3045 assert_eq!(chunks.prev(), None);
3046 }
3047
3048 #[test]
3049 #[cfg_attr(miri, ignore)]
3050 fn chunks_at_char_01() {
3051 let r = Rope::from_str(TEXT);
3052
3053 for i in 0..r.len_chars() {
3054 let (chunk, b, c, l) = r.chunk_at_char(i);
3055 let (mut chunks, bs, cs, ls) = r.chunks_at_char(i);
3056
3057 assert_eq!(b, bs);
3058 assert_eq!(c, cs);
3059 assert_eq!(l, ls);
3060 assert_eq!(Some(chunk), chunks.next());
3061 }
3062 }
3063
3064 #[test]
3065 #[cfg_attr(miri, ignore)]
3066 fn chunks_at_char_02() {
3067 let r = Rope::from_str(TEXT);
3068 let s = r.slice(34..301);
3069
3070 for i in 0..s.len_chars() {
3071 let (chunk, b, c, l) = s.chunk_at_char(i);
3072 let (mut chunks, bs, cs, ls) = s.chunks_at_char(i);
3073
3074 assert_eq!(b, bs);
3075 assert_eq!(c, cs);
3076 assert_eq!(l, ls);
3077 assert_eq!(Some(chunk), chunks.next());
3078 }
3079 }
3080
3081 #[test]
3082 #[cfg_attr(miri, ignore)]
3083 fn chunks_at_char_03() {
3084 let r = Rope::from_str(TEXT);
3085 let s = r.slice(34..301);
3086
3087 let (mut chunks, _, _, _) = s.chunks_at_char(s.len_chars());
3088 assert_eq!(chunks.next(), None);
3089 }
3090
3091 #[test]
3092 #[cfg_attr(miri, ignore)]
3093 fn chunks_at_char_04() {
3094 let r = Rope::from_str(TEXT);
3095 let s = r.slice(34..34);
3096
3097 let (mut chunks, _, _, _) = s.chunks_at_char(0);
3098 assert_eq!(chunks.next(), None);
3099
3100 let (mut chunks, _, _, _) = s.chunks_at_char(0);
3101 assert_eq!(chunks.prev(), None);
3102 }
3103
3104 #[test]
3105 #[cfg_attr(miri, ignore)]
3106 fn chunks_at_line_break_01() {
3107 let r = Rope::from_str(TEXT);
3108
3109 for i in 0..r.len_lines() {
3110 let (chunk, b, c, l) = r.chunk_at_line_break(i);
3111 let (mut chunks, bs, cs, ls) = r.chunks_at_line_break(i);
3112
3113 assert_eq!(b, bs);
3114 assert_eq!(c, cs);
3115 assert_eq!(l, ls);
3116 assert_eq!(Some(chunk), chunks.next());
3117 }
3118 }
3119
3120 #[test]
3121 #[cfg_attr(miri, ignore)]
3122 fn chunks_at_line_break_02() {
3123 let r = Rope::from_str(TEXT);
3124 let s = r.slice(34..301);
3125
3126 for i in 0..s.len_lines() {
3127 let (chunk, b, c, l) = s.chunk_at_line_break(i);
3128 let (mut chunks, bs, cs, ls) = s.chunks_at_line_break(i);
3129
3130 assert_eq!(Some(chunk), chunks.next());
3131 assert_eq!(b, bs);
3132 assert_eq!(c, cs);
3133 assert_eq!(l, ls);
3134 }
3135 }
3136
3137 #[test]
3138 #[cfg_attr(miri, ignore)]
3139 fn chunks_at_line_break_03() {
3140 let r = Rope::from_str(TEXT);
3141 let s = r.slice(34..301);
3142
3143 let (mut chunks, _, _, _) = s.chunks_at_line_break(s.len_lines());
3144 assert_eq!(chunks.next(), None);
3145 }
3146
3147 #[test]
3148 #[cfg_attr(miri, ignore)]
3149 fn chunks_at_line_break_04() {
3150 let r = Rope::from_str(TEXT);
3151 let s = r.slice(34..34);
3152
3153 let (mut chunks, _, _, _) = s.chunks_at_line_break(0);
3154 assert_eq!(chunks.next(), None);
3155
3156 let (mut chunks, _, _, _) = s.chunks_at_line_break(0);
3157 assert_eq!(chunks.prev(), None);
3158 }
3159
3160 #[test]
3161 #[cfg_attr(miri, ignore)]
3162 fn chunks_reverse_01() {
3163 let r = Rope::from_str(TEXT);
3164 let mut itr = r.chunks();
3165 let mut stack = Vec::new();
3166
3167 for _ in 0..8 {
3168 stack.push(itr.next().unwrap());
3169 }
3170 itr.reverse();
3171 for _ in 0..8 {
3172 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
3173 }
3174 }
3175
3176 #[test]
3177 #[cfg_attr(miri, ignore)]
3178 fn chunks_reverse_02() {
3179 let r = Rope::from_str(TEXT);
3180 let mut itr = r.chunks_at_char(r.len_chars() / 3).0;
3181 let mut stack = Vec::new();
3182
3183 for _ in 0..8 {
3184 stack.push(itr.next().unwrap());
3185 }
3186 itr.reverse();
3187 for _ in 0..8 {
3188 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
3189 }
3190 }
3191
3192 #[test]
3193 #[cfg_attr(miri, ignore)]
3194 fn chunks_reverse_03() {
3195 let r = Rope::from_str(TEXT);
3196 let mut itr = r.chunks_at_char(r.len_chars() / 3).0;
3197 let mut stack = Vec::new();
3198
3199 itr.reverse();
3200 for _ in 0..8 {
3201 stack.push(itr.next().unwrap());
3202 }
3203 itr.reverse();
3204 for _ in 0..8 {
3205 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
3206 }
3207 }
3208
3209 #[test]
3210 #[cfg_attr(miri, ignore)]
3211 fn chunks_reverse_04() {
3212 let mut itr = Chunks::from_str("a\n", false);
3213
3214 assert_eq!(Some("a\n"), itr.next());
3215 assert_eq!(None, itr.next());
3216 itr.reverse();
3217 assert_eq!(Some("a\n"), itr.next());
3218 assert_eq!(None, itr.next());
3219 }
3220
3221 #[test]
3222 #[cfg_attr(miri, ignore)]
3223 fn bytes_sliced_01() {
3224 let r = Rope::from_str(TEXT);
3225
3226 let s_start = 34;
3227 let s_end = 301;
3228 let s_start_byte = r.char_to_byte(s_start);
3229 let s_end_byte = r.char_to_byte(s_end);
3230
3231 let s1 = r.slice(s_start..s_end);
3232 let s2 = &TEXT[s_start_byte..s_end_byte];
3233
3234 let mut s1_bytes = s1.bytes();
3235 let mut s2_bytes = s2.bytes();
3236
3237 assert_eq!(s1, s2);
3238 assert_eq!(s1.byte(0), s2.as_bytes()[0]);
3239
3240 assert_eq!(s1.len_bytes(), s2.len());
3241 assert_eq!(s1_bytes.len(), s2.len());
3242
3243 for _ in 0..(s2.len() + 1) {
3244 assert_eq!(s1_bytes.next(), s2_bytes.next());
3245 }
3246
3247 assert_eq!(s1_bytes.len(), 0);
3248 }
3249
3250 #[test]
3251 #[cfg_attr(miri, ignore)]
3252 fn bytes_sliced_reverse_01() {
3253 let r = Rope::from_str(TEXT);
3254
3255 let s_start = 34;
3256 let s_end = 301;
3257 let s = r.slice(s_start..s_end);
3258
3259 let mut itr = s.bytes();
3260 let mut stack = Vec::new();
3261 for _ in 0..32 {
3262 stack.push(itr.next().unwrap());
3263 }
3264 itr.reverse();
3265 for _ in 0..32 {
3266 assert_eq!(stack.pop(), itr.next());
3267 }
3268 }
3269
3270 #[test]
3271 #[cfg_attr(miri, ignore)]
3272 fn bytes_at_sliced_01() {
3273 let r = Rope::from_str(TEXT);
3274
3275 let s_start = 34;
3276 let s_end = 301;
3277 let s_start_byte = r.char_to_byte(s_start);
3278 let s_end_byte = r.char_to_byte(s_end);
3279
3280 let s1 = r.slice(s_start..s_end);
3281 let s2 = &TEXT[s_start_byte..s_end_byte];
3282
3283 let mut bytes_1 = s2.bytes();
3284 for i in 0..(s1.len_bytes() + 1) {
3285 let mut bytes_2 = s1.bytes_at(i);
3286 assert_eq!(bytes_1.next(), bytes_2.next());
3287 }
3288 }
3289
3290 #[test]
3291 #[cfg_attr(miri, ignore)]
3292 fn bytes_at_sliced_02() {
3293 let r = Rope::from_str(TEXT);
3294 let s = r.slice(34..301);
3295 let mut bytes = s.bytes_at(s.len_bytes());
3296 assert_eq!(bytes.next(), None);
3297 }
3298
3299 #[test]
3300 #[cfg_attr(miri, ignore)]
3301 fn bytes_at_sliced_03() {
3302 let r = Rope::from_str(TEXT);
3303
3304 let s_start = 34;
3305 let s_end = 301;
3306 let s_start_byte = r.char_to_byte(s_start);
3307 let s_end_byte = r.char_to_byte(s_end);
3308
3309 let s1 = r.slice(s_start..s_end);
3310 let s2 = &TEXT[s_start_byte..s_end_byte];
3311
3312 let mut bytes_1 = s1.bytes_at(s1.len_bytes());
3313 let mut bytes_2 = s2.bytes();
3314 while let Some(b) = bytes_2.next_back() {
3315 assert_eq!(bytes_1.prev(), Some(b));
3316 }
3317 }
3318
3319 #[test]
3320 #[cfg_attr(miri, ignore)]
3321 fn bytes_at_sliced_reverse_01() {
3322 let r = Rope::from_str(TEXT);
3323
3324 let s_start = 34;
3325 let s_end = 301;
3326 let s = r.slice(s_start..s_end);
3327
3328 let mut itr = s.bytes_at(s.len_bytes() / 3);
3329 let mut stack = Vec::new();
3330 for _ in 0..32 {
3331 stack.push(itr.next().unwrap());
3332 }
3333 itr.reverse();
3334 for _ in 0..32 {
3335 assert_eq!(stack.pop(), itr.next());
3336 }
3337 }
3338
3339 #[test]
3340 #[cfg_attr(miri, ignore)]
3341 fn chars_sliced_01() {
3342 let r = Rope::from_str(TEXT);
3343
3344 let s_start = 34;
3345 let s_end = 301;
3346 let s_start_byte = r.char_to_byte(s_start);
3347 let s_end_byte = r.char_to_byte(s_end);
3348
3349 let s1 = r.slice(s_start..s_end);
3350 let s2 = &TEXT[s_start_byte..s_end_byte];
3351
3352 for (cr, ct) in s1.chars().zip(s2.chars()) {
3353 assert_eq!(cr, ct);
3354 }
3355 }
3356
3357 #[test]
3358 #[cfg_attr(miri, ignore)]
3359 fn chars_sliced_reverse_01() {
3360 let r = Rope::from_str(TEXT);
3361
3362 let s_start = 34;
3363 let s_end = 301;
3364 let s = r.slice(s_start..s_end);
3365
3366 let mut itr = s.chars();
3367 let mut stack = Vec::new();
3368 for _ in 0..32 {
3369 stack.push(itr.next().unwrap());
3370 }
3371 itr.reverse();
3372 for _ in 0..32 {
3373 assert_eq!(stack.pop(), itr.next());
3374 }
3375 }
3376
3377 #[test]
3378 #[cfg_attr(miri, ignore)]
3379 fn chars_at_sliced_01() {
3380 let r = Rope::from_str(TEXT);
3381
3382 let s_start = 34;
3383 let s_end = 301;
3384 let s_start_byte = r.char_to_byte(s_start);
3385 let s_end_byte = r.char_to_byte(s_end);
3386
3387 let s1 = r.slice(s_start..s_end);
3388 let s2 = &TEXT[s_start_byte..s_end_byte];
3389
3390 let mut chars_1 = s2.chars();
3391 for i in 0..(s1.len_chars() + 1) {
3392 let mut chars_2 = s1.chars_at(i);
3393 assert_eq!(chars_1.next(), chars_2.next());
3394 }
3395 }
3396
3397 #[test]
3398 #[cfg_attr(miri, ignore)]
3399 fn chars_at_sliced_02() {
3400 let r = Rope::from_str(TEXT);
3401 let s = r.slice(34..301);
3402 let mut chars = s.chars_at(s.len_chars());
3403 assert_eq!(chars.next(), None);
3404 }
3405
3406 #[test]
3407 #[cfg_attr(miri, ignore)]
3408 fn chars_at_sliced_03() {
3409 let r = Rope::from_str(TEXT);
3410
3411 let s_start = 34;
3412 let s_end = 301;
3413 let s_start_char = r.char_to_byte(s_start);
3414 let s_end_char = r.char_to_byte(s_end);
3415
3416 let s1 = r.slice(s_start..s_end);
3417 let s2 = &TEXT[s_start_char..s_end_char];
3418
3419 let mut chars_1 = s1.chars_at(s1.len_chars());
3420 let mut chars_2 = s2.chars();
3421 while let Some(c) = chars_2.next_back() {
3422 assert_eq!(chars_1.prev(), Some(c));
3423 }
3424 }
3425
3426 #[test]
3427 #[cfg_attr(miri, ignore)]
3428 fn chars_at_sliced_reverse_01() {
3429 let r = Rope::from_str(TEXT);
3430
3431 let s_start = 34;
3432 let s_end = 301;
3433 let s = r.slice(s_start..s_end);
3434
3435 let mut itr = s.chars_at(s.len_chars() / 3);
3436 let mut stack = Vec::new();
3437 for _ in 0..32 {
3438 stack.push(itr.next().unwrap());
3439 }
3440 itr.reverse();
3441 for _ in 0..32 {
3442 assert_eq!(stack.pop(), itr.next());
3443 }
3444 }
3445
3446 #[test]
3447 #[cfg_attr(miri, ignore)]
3448 fn lines_sliced_01() {
3449 let r = Rope::from_str(TEXT);
3450
3451 let s_start = 34;
3452 let s_end = 301;
3453 let s_start_byte = r.char_to_byte(s_start);
3454 let s_end_byte = r.char_to_byte(s_end);
3455
3456 let s1 = r.slice(s_start..s_end);
3457 let s2 = &TEXT[s_start_byte..s_end_byte];
3458
3459 for (liner, linet) in s1.lines().zip(s2.lines()) {
3460 assert_eq!(liner.to_string().trim_end(), linet);
3461 }
3462 }
3463
3464 #[test]
3465 #[cfg_attr(miri, ignore)]
3466 fn lines_sliced_reverse_01() {
3467 let r = Rope::from_str(TEXT);
3468
3469 let s_start = 34;
3470 let s_end = 301;
3471 let s = r.slice(s_start..s_end);
3472
3473 let mut itr = s.lines();
3474 let mut stack = Vec::new();
3475 for _ in 0..4 {
3476 stack.push(itr.next().unwrap());
3477 }
3478 itr.reverse();
3479 for _ in 0..4 {
3480 assert_eq!(stack.pop().unwrap(), itr.next().unwrap());
3481 }
3482 }
3483
3484 #[test]
3485 #[cfg_attr(miri, ignore)]
3486 fn chunks_sliced_01() {
3487 let r = Rope::from_str(TEXT);
3488
3489 let s_start = 34;
3490 let s_end = 301;
3491 let s_start_byte = r.char_to_byte(s_start);
3492 let s_end_byte = r.char_to_byte(s_end);
3493
3494 let s1 = r.slice(s_start..s_end);
3495 let s2 = &TEXT[s_start_byte..s_end_byte];
3496
3497 let mut idx = 0;
3498 for chunk in s1.chunks() {
3499 assert_eq!(chunk, &s2[idx..(idx + chunk.len())]);
3500 idx += chunk.len();
3501 }
3502
3503 assert_eq!(idx, s2.len());
3504 }
3505
3506 #[test]
3507 #[cfg_attr(miri, ignore)]
3508 fn chunks_sliced_reverse_01() {
3509 let r = Rope::from_str(TEXT);
3510
3511 let s_start = 34;
3512 let s_end = 301;
3513 let s = r.slice(s_start..s_end);
3514
3515 let mut itr = s.chunks();
3516 let mut stack = Vec::new();
3517 for _ in 0..8 {
3518 stack.push(itr.next().unwrap());
3519 }
3520 itr.reverse();
3521 for _ in 0..8 {
3522 assert_eq!(stack.pop(), itr.next());
3523 }
3524 }
3525
3526 #[test]
3527 #[cfg_attr(miri, ignore)]
3528 fn empty_iter() {
3529 let rope = Rope::from_str("");
3530 let r: Vec<_> = rope.lines().collect();
3531 assert_eq!(&[""], &*r)
3532 }
3533}