1use std::io;
2use std::iter::FromIterator;
3use std::ops::RangeBounds;
4use std::sync::Arc;
5
6use crate::crlf;
7use crate::iter::{Bytes, Chars, Chunks, Lines};
8use crate::rope_builder::RopeBuilder;
9use crate::slice::RopeSlice;
10use crate::str_utils::{
11 byte_to_char_idx, byte_to_line_idx, byte_to_utf16_surrogate_idx, char_to_byte_idx,
12 char_to_line_idx, line_to_byte_idx, line_to_char_idx, utf16_code_unit_to_char_idx,
13};
14use crate::tree::{Count, Node, NodeChildren, TextInfo, MAX_BYTES, MIN_BYTES};
15use crate::{end_bound_to_num, start_bound_to_num, Error, Result};
16
17#[derive(Clone)]
82pub struct Rope {
83 pub(crate) root: Arc<Node>,
84}
85
86impl Rope {
87 #[inline]
92 pub fn new() -> Self {
93 Rope {
94 root: Arc::new(Node::new()),
95 }
96 }
97
98 #[inline]
102 #[allow(clippy::should_implement_trait)]
103 pub fn from_str(text: &str) -> Self {
104 RopeBuilder::new().build_at_once(text)
105 }
106
107 #[allow(unused_mut)]
129 pub fn from_reader<T: io::Read>(mut reader: T) -> io::Result<Self> {
130 const BUFFER_SIZE: usize = MAX_BYTES * 2;
131 let mut builder = RopeBuilder::new();
132 let mut buffer = [0u8; BUFFER_SIZE];
133 let mut fill_idx = 0; loop {
135 match reader.read(&mut buffer[fill_idx..]) {
136 Ok(read_count) => {
137 fill_idx += read_count;
138
139 let valid_count = match std::str::from_utf8(&buffer[..fill_idx]) {
141 Ok(_) => fill_idx,
142 Err(e) => e.valid_up_to(),
143 };
144
145 if valid_count > 0 {
147 builder.append(unsafe {
152 std::str::from_utf8_unchecked(&buffer[..valid_count])
153 });
154 }
155
156 if valid_count < fill_idx {
158 buffer.copy_within(valid_count..fill_idx, 0);
159 }
160 fill_idx -= valid_count;
161
162 if fill_idx == BUFFER_SIZE {
163 return Err(io::Error::new(
167 io::ErrorKind::InvalidData,
168 "stream did not contain valid UTF-8",
169 ));
170 }
171
172 if read_count == 0 {
174 if fill_idx > 0 {
175 return Err(io::Error::new(
177 io::ErrorKind::InvalidData,
178 "stream contained invalid UTF-8",
179 ));
180 } else {
181 return Ok(builder.finish());
182 }
183 }
184 }
185
186 Err(e) => {
187 return Err(e);
189 }
190 }
191 }
192 }
193
194 #[allow(unused_mut)]
216 pub fn write_to<T: io::Write>(&self, mut writer: T) -> io::Result<()> {
217 for chunk in self.chunks() {
218 writer.write_all(chunk.as_bytes())?;
219 }
220
221 Ok(())
222 }
223
224 #[inline]
231 pub fn len_bytes(&self) -> usize {
232 self.root.byte_count()
233 }
234
235 #[inline]
239 pub fn len_chars(&self) -> usize {
240 self.root.char_count()
241 }
242
243 #[inline]
247 pub fn len_lines(&self) -> usize {
248 self.root.line_break_count() + 1
249 }
250
251 #[inline]
261 pub fn len_utf16_cu(&self) -> usize {
262 let info = self.root.text_info();
263 (info.chars + info.utf16_surrogates) as usize
264 }
265
266 pub fn capacity(&self) -> usize {
277 let mut byte_count = 0;
278 for chunk in self.chunks() {
279 byte_count += chunk.len().max(MAX_BYTES);
280 }
281 byte_count
282 }
283
284 pub fn shrink_to_fit(&mut self) {
304 let mut node_stack = Vec::new();
305 let mut builder = RopeBuilder::new();
306
307 node_stack.push(self.root.clone());
308 *self = Rope::new();
309
310 loop {
311 if node_stack.is_empty() {
312 break;
313 }
314
315 if node_stack.last().unwrap().is_leaf() {
316 builder.append(node_stack.last().unwrap().leaf_text());
317 node_stack.pop();
318 } else if node_stack.last().unwrap().child_count() == 0 {
319 node_stack.pop();
320 } else {
321 let (_, next_node) = Arc::make_mut(node_stack.last_mut().unwrap())
322 .children_mut()
323 .remove(0);
324 node_stack.push(next_node);
325 }
326 }
327
328 *self = builder.finish();
329 }
330
331 #[inline]
343 pub fn insert(&mut self, char_idx: usize, text: &str) {
344 self.try_insert(char_idx, text).unwrap()
346 }
347
348 #[inline]
356 pub fn insert_char(&mut self, char_idx: usize, ch: char) {
357 self.try_insert_char(char_idx, ch).unwrap()
358 }
359
360 fn insert_internal(&mut self, char_idx: usize, ins_text: &str) {
370 let mut ins_text = ins_text;
371 let mut left_seam = false;
372 let root_info = self.root.text_info();
373
374 let (l_info, residual) = Arc::make_mut(&mut self.root).edit_chunk_at_char(
375 char_idx,
376 root_info,
377 |idx, cur_info, leaf_text| {
378 if idx == 0 && char_idx > 0 && ins_text.as_bytes()[0] == 0x0A {
380 left_seam = true;
381 ins_text = &ins_text[1..];
382 if ins_text.is_empty() {
384 return (cur_info, None);
385 }
386 }
387
388 let byte_idx = char_to_byte_idx(leaf_text, idx);
390
391 if (leaf_text.len() + ins_text.len()) <= MAX_BYTES {
393 let new_info = {
395 #[allow(unused_mut)]
397 let mut info = cur_info + TextInfo::from_str(ins_text);
398 #[cfg(any(feature = "cr_lines", feature = "unicode_lines"))]
401 {
402 if byte_idx > 0 {
403 if leaf_text.as_bytes()[byte_idx - 1] == 0x0D
404 && ins_text.as_bytes()[0] == 0x0A
405 {
406 info.line_breaks -= 1;
407 }
408 if byte_idx < leaf_text.len()
409 && leaf_text.as_bytes()[byte_idx - 1] == 0x0D
410 && leaf_text.as_bytes()[byte_idx] == 0x0A
411 {
412 info.line_breaks += 1;
413 }
414 }
415 if byte_idx < leaf_text.len()
416 && *ins_text.as_bytes().last().unwrap() == 0x0D
417 && leaf_text.as_bytes()[byte_idx] == 0x0A
418 {
419 info.line_breaks -= 1;
420 }
421 }
422 info
423 };
424 leaf_text.insert_str(byte_idx, ins_text);
426 (new_info, None)
427 }
428 else {
430 let r_text = leaf_text.insert_str_split(byte_idx, ins_text);
431 let l_text_info = TextInfo::from_str(leaf_text);
432 if r_text.len() > 0 {
433 let r_text_info = TextInfo::from_str(&r_text);
434 (
435 l_text_info,
436 Some((r_text_info, Arc::new(Node::Leaf(r_text)))),
437 )
438 } else {
439 (l_text_info, None)
441 }
442 }
443 },
444 );
445
446 if let Some((r_info, r_node)) = residual {
448 let mut l_node = Arc::new(Node::new());
449 std::mem::swap(&mut l_node, &mut self.root);
450
451 let mut children = NodeChildren::new();
452 children.push((l_info, l_node));
453 children.push((r_info, r_node));
454
455 *Arc::make_mut(&mut self.root) = Node::Internal(children);
456 }
457
458 if left_seam {
462 let root_info = self.root.text_info();
464 let (l_info, residual) = Arc::make_mut(&mut self.root).edit_chunk_at_char(
465 char_idx - 1,
466 root_info,
467 |_, cur_info, leaf_text| {
468 let byte_idx = leaf_text.len();
469
470 if (leaf_text.len() + ins_text.len()) <= MAX_BYTES {
472 let mut new_info = cur_info;
474 new_info.bytes += 1;
475 new_info.chars += 1;
476 #[cfg(not(any(feature = "cr_lines", feature = "unicode_lines")))]
477 {
478 new_info.line_breaks += 1;
479 }
480 #[cfg(any(feature = "cr_lines", feature = "unicode_lines"))]
481 if *leaf_text.as_bytes().last().unwrap() != 0x0D {
482 new_info.line_breaks += 1;
483 }
484 leaf_text.insert_str(byte_idx, "\n");
486 (new_info, None)
487 }
488 else {
490 let r_text = leaf_text.insert_str_split(byte_idx, "\n");
491 let l_text_info = TextInfo::from_str(leaf_text);
492 if r_text.len() > 0 {
493 let r_text_info = TextInfo::from_str(&r_text);
494 (
495 l_text_info,
496 Some((r_text_info, Arc::new(Node::Leaf(r_text)))),
497 )
498 } else {
499 (l_text_info, None)
501 }
502 }
503 },
504 );
505
506 if let Some((r_info, r_node)) = residual {
508 let mut l_node = Arc::new(Node::new());
509 std::mem::swap(&mut l_node, &mut self.root);
510
511 let mut children = NodeChildren::new();
512 children.push((l_info, l_node));
513 children.push((r_info, r_node));
514
515 *Arc::make_mut(&mut self.root) = Node::Internal(children);
516 }
517 }
518 }
519
520 pub fn remove<R>(&mut self, char_range: R)
543 where
544 R: RangeBounds<usize>,
545 {
546 self.try_remove(char_range).unwrap()
547 }
548
549 pub fn split_off(&mut self, char_idx: usize) -> Self {
558 self.try_split_off(char_idx).unwrap()
559 }
560
561 pub fn append(&mut self, other: Self) {
565 if self.len_chars() == 0 {
566 let mut other = other;
568 std::mem::swap(self, &mut other);
569 } else if other.len_chars() > 0 {
570 let left_info = self.root.text_info();
571 let right_info = other.root.text_info();
572
573 let seam_byte_i = if other.char(0) == '\n' {
574 Some(left_info.bytes)
575 } else {
576 None
577 };
578
579 let l_depth = self.root.depth();
580 let r_depth = other.root.depth();
581
582 if l_depth > r_depth {
583 let extra =
584 Arc::make_mut(&mut self.root).append_at_depth(other.root, l_depth - r_depth);
585 if let Some(node) = extra {
586 let mut children = NodeChildren::new();
587 children.push((self.root.text_info(), Arc::clone(&self.root)));
588 children.push((node.text_info(), node));
589 self.root = Arc::new(Node::Internal(children));
590 }
591 } else {
592 let mut other = other;
593 let extra = Arc::make_mut(&mut other.root)
594 .prepend_at_depth(Arc::clone(&self.root), r_depth - l_depth);
595 if let Some(node) = extra {
596 let mut children = NodeChildren::new();
597 children.push((node.text_info(), node));
598 children.push((other.root.text_info(), Arc::clone(&other.root)));
599 other.root = Arc::new(Node::Internal(children));
600 }
601 *self = other;
602 };
603
604 let root = Arc::make_mut(&mut self.root);
606 if let Some(i) = seam_byte_i {
607 root.fix_crlf_seam(i, true);
608 }
609 if (left_info.bytes as usize) < MIN_BYTES || (right_info.bytes as usize) < MIN_BYTES {
610 root.fix_tree_seam(left_info.chars as usize);
611 }
612 self.pull_up_singular_nodes();
613 }
614 }
615
616 #[inline]
634 pub fn byte_to_char(&self, byte_idx: usize) -> usize {
635 self.try_byte_to_char(byte_idx).unwrap()
636 }
637
638 #[inline]
653 pub fn byte_to_line(&self, byte_idx: usize) -> usize {
654 self.try_byte_to_line(byte_idx).unwrap()
655 }
656
657 #[inline]
670 pub fn char_to_byte(&self, char_idx: usize) -> usize {
671 self.try_char_to_byte(char_idx).unwrap()
672 }
673
674 #[inline]
689 pub fn char_to_line(&self, char_idx: usize) -> usize {
690 self.try_char_to_line(char_idx).unwrap()
691 }
692
693 #[inline]
706 pub fn char_to_utf16_cu(&self, char_idx: usize) -> usize {
707 self.try_char_to_utf16_cu(char_idx).unwrap()
708 }
709
710 #[inline]
727 pub fn utf16_cu_to_char(&self, utf16_cu_idx: usize) -> usize {
728 self.try_utf16_cu_to_char(utf16_cu_idx).unwrap()
729 }
730
731 #[inline]
745 pub fn line_to_byte(&self, line_idx: usize) -> usize {
746 self.try_line_to_byte(line_idx).unwrap()
747 }
748
749 #[inline]
763 pub fn line_to_char(&self, line_idx: usize) -> usize {
764 self.try_line_to_char(line_idx).unwrap()
765 }
766
767 #[inline]
778 pub fn byte(&self, byte_idx: usize) -> u8 {
779 if let Some(out) = self.get_byte(byte_idx) {
781 out
782 } else {
783 panic!(
784 "Attempt to index past end of Rope: byte index {}, Rope byte length {}",
785 byte_idx,
786 self.len_bytes()
787 );
788 }
789 }
790
791 #[inline]
799 pub fn char(&self, char_idx: usize) -> char {
800 if let Some(out) = self.get_char(char_idx) {
801 out
802 } else {
803 panic!(
804 "Attempt to index past end of Rope: char index {}, Rope char length {}",
805 char_idx,
806 self.len_chars()
807 );
808 }
809 }
810
811 #[inline]
821 pub fn line(&self, line_idx: usize) -> RopeSlice {
822 if let Some(out) = self.get_line(line_idx) {
823 out
824 } else {
825 let len_lines = self.len_lines();
826 panic!(
827 "Attempt to index past end of Rope: line index {}, Rope line length {}",
828 line_idx, len_lines
829 );
830 }
831 }
832
833 #[inline]
850 pub fn chunk_at_byte(&self, byte_idx: usize) -> (&str, usize, usize, usize) {
851 if let Some(out) = self.get_chunk_at_byte(byte_idx) {
853 out
854 } else {
855 panic!(
856 "Attempt to index past end of Rope: byte index {}, Rope byte length {}",
857 byte_idx,
858 self.len_bytes()
859 );
860 }
861 }
862
863 #[inline]
880 pub fn chunk_at_char(&self, char_idx: usize) -> (&str, usize, usize, usize) {
881 if let Some(out) = self.get_chunk_at_char(char_idx) {
882 out
883 } else {
884 panic!(
885 "Attempt to index past end of Rope: char index {}, Rope char length {}",
886 char_idx,
887 self.len_chars()
888 );
889 }
890 }
891
892 #[inline]
912 pub fn chunk_at_line_break(&self, line_break_idx: usize) -> (&str, usize, usize, usize) {
913 if let Some(out) = self.get_chunk_at_line_break(line_break_idx) {
914 out
915 } else {
916 panic!(
917 "Attempt to index past end of Rope: line break index {}, max index {}",
918 line_break_idx,
919 self.len_lines()
920 );
921 }
922 }
923
924 #[inline]
948 pub fn slice<R>(&self, char_range: R) -> RopeSlice
949 where
950 R: RangeBounds<usize>,
951 {
952 self.get_slice(char_range).unwrap()
953 }
954
955 pub fn byte_slice<R>(&self, byte_range: R) -> RopeSlice
968 where
969 R: RangeBounds<usize>,
970 {
971 match self.get_byte_slice_impl(byte_range) {
972 Ok(s) => return s,
973 Err(e) => panic!("byte_slice(): {}", e),
974 }
975 }
976
977 #[inline]
984 pub fn bytes(&self) -> Bytes {
985 Bytes::new(&self.root)
986 }
987
988 #[inline]
1000 pub fn bytes_at(&self, byte_idx: usize) -> Bytes {
1001 if let Some(out) = self.get_bytes_at(byte_idx) {
1002 out
1003 } else {
1004 panic!(
1005 "Attempt to index past end of Rope: byte index {}, Rope byte length {}",
1006 byte_idx,
1007 self.len_bytes()
1008 );
1009 }
1010 }
1011
1012 #[inline]
1016 pub fn chars(&self) -> Chars {
1017 Chars::new(&self.root)
1018 }
1019
1020 #[inline]
1032 pub fn chars_at(&self, char_idx: usize) -> Chars {
1033 if let Some(out) = self.get_chars_at(char_idx) {
1034 out
1035 } else {
1036 panic!(
1037 "Attempt to index past end of Rope: char index {}, Rope char length {}",
1038 char_idx,
1039 self.len_chars()
1040 );
1041 }
1042 }
1043
1044 #[inline]
1048 pub fn lines(&self) -> Lines {
1049 Lines::new(&self.root)
1050 }
1051
1052 #[inline]
1064 pub fn lines_at(&self, line_idx: usize) -> Lines {
1065 if let Some(out) = self.get_lines_at(line_idx) {
1066 out
1067 } else {
1068 panic!(
1069 "Attempt to index past end of Rope: line index {}, Rope line length {}",
1070 line_idx,
1071 self.len_lines()
1072 );
1073 }
1074 }
1075
1076 #[inline]
1080 pub fn chunks(&self) -> Chunks {
1081 Chunks::new(&self.root)
1082 }
1083
1084 #[inline]
1102 pub fn chunks_at_byte(&self, byte_idx: usize) -> (Chunks, usize, usize, usize) {
1103 if let Some(out) = self.get_chunks_at_byte(byte_idx) {
1104 out
1105 } else {
1106 panic!(
1107 "Attempt to index past end of Rope: byte index {}, Rope byte length {}",
1108 byte_idx,
1109 self.len_bytes()
1110 );
1111 }
1112 }
1113
1114 #[inline]
1132 pub fn chunks_at_char(&self, char_idx: usize) -> (Chunks, usize, usize, usize) {
1133 if let Some(out) = self.get_chunks_at_char(char_idx) {
1134 out
1135 } else {
1136 panic!(
1137 "Attempt to index past end of Rope: char index {}, Rope char length {}",
1138 char_idx,
1139 self.len_chars()
1140 );
1141 }
1142 }
1143
1144 #[inline]
1166 pub fn chunks_at_line_break(&self, line_break_idx: usize) -> (Chunks, usize, usize, usize) {
1167 if let Some(out) = self.get_chunks_at_line_break(line_break_idx) {
1168 out
1169 } else {
1170 panic!(
1171 "Attempt to index past end of Rope: line break index {}, max index {}",
1172 line_break_idx,
1173 self.len_lines()
1174 );
1175 }
1176 }
1177
1178 #[inline]
1195 pub fn is_instance(&self, other: &Rope) -> bool {
1196 Arc::ptr_eq(&self.root, &other.root)
1197 }
1198
1199 #[doc(hidden)]
1207 pub fn assert_integrity(&self) {
1208 self.root.assert_integrity();
1209 }
1210
1211 #[doc(hidden)]
1221 pub fn assert_invariants(&self) {
1222 self.root.assert_balance();
1223 self.root.assert_node_size(true);
1224 self.assert_crlf_seams();
1225 }
1226
1227 fn assert_crlf_seams(&self) {
1229 if self.chunks().count() > 0 {
1230 let mut itr = self.chunks();
1231 let mut last_chunk = itr.next().unwrap();
1232 for chunk in itr {
1233 if !chunk.is_empty() && !last_chunk.is_empty() {
1234 assert!(crlf::seam_is_break(last_chunk.as_bytes(), chunk.as_bytes()));
1235 last_chunk = chunk;
1236 } else if last_chunk.is_empty() {
1237 last_chunk = chunk;
1238 }
1239 }
1240 }
1241 }
1242
1243 pub(crate) fn pull_up_singular_nodes(&mut self) {
1249 while (!self.root.is_leaf()) && self.root.child_count() == 1 {
1250 let child = if let Node::Internal(ref children) = *self.root {
1251 Arc::clone(&children.nodes()[0])
1252 } else {
1253 unreachable!()
1254 };
1255
1256 self.root = child;
1257 }
1258 }
1259}
1260
1261impl Rope {
1267 #[inline]
1269 pub fn try_insert(&mut self, char_idx: usize, text: &str) -> Result<()> {
1270 if char_idx <= self.len_chars() {
1272 if text.len() > MAX_BYTES * 6 {
1291 let text_rope = Rope::from_str(text);
1293 let right = self.split_off(char_idx);
1294 self.append(text_rope);
1295 self.append(right);
1296 } else {
1297 let mut text = text;
1299 while !text.is_empty() {
1300 let split_idx = crlf::find_good_split(
1305 text.len() - (MAX_BYTES - 4).min(text.len()),
1306 text.as_bytes(),
1307 false,
1308 );
1309 let ins_text = &text[split_idx..];
1310 text = &text[..split_idx];
1311
1312 self.insert_internal(char_idx, ins_text);
1314 }
1315 }
1316 Ok(())
1317 } else {
1318 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1319 }
1320 }
1321
1322 #[inline]
1324 pub fn try_insert_char(&mut self, char_idx: usize, ch: char) -> Result<()> {
1325 if char_idx <= self.len_chars() {
1327 let mut buf = [0u8; 4];
1328 self.insert_internal(char_idx, ch.encode_utf8(&mut buf));
1329 Ok(())
1330 } else {
1331 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1332 }
1333 }
1334
1335 pub fn try_remove<R>(&mut self, char_range: R) -> Result<()>
1337 where
1338 R: RangeBounds<usize>,
1339 {
1340 let start_opt = start_bound_to_num(char_range.start_bound());
1341 let end_opt = end_bound_to_num(char_range.end_bound());
1342 let start = start_opt.unwrap_or(0);
1343 let end = end_opt.unwrap_or_else(|| self.len_chars());
1344 if end.max(start) > self.len_chars() {
1345 Err(Error::CharRangeOutOfBounds(
1346 start_opt,
1347 end_opt,
1348 self.len_chars(),
1349 ))
1350 } else if start > end {
1351 Err(Error::CharRangeInvalid(start, end))
1352 } else {
1353 if start == 0 && end == self.len_chars() {
1356 self.root = Arc::new(Node::new());
1357 return Ok(());
1358 }
1359
1360 let root = Arc::make_mut(&mut self.root);
1361
1362 let root_info = root.text_info();
1363 let (_, crlf_seam, needs_fix) = root.remove_char_range(start, end, root_info);
1364
1365 if crlf_seam {
1366 let seam_idx = root.char_to_text_info(start).bytes;
1367 root.fix_crlf_seam(seam_idx as Count, false);
1368 }
1369
1370 if needs_fix {
1371 root.fix_tree_seam(start);
1372 }
1373
1374 self.pull_up_singular_nodes();
1375 Ok(())
1376 }
1377 }
1378
1379 pub fn try_split_off(&mut self, char_idx: usize) -> Result<Self> {
1381 if char_idx <= self.len_chars() {
1383 if char_idx == 0 {
1384 let mut new_rope = Rope::new();
1386 std::mem::swap(self, &mut new_rope);
1387 Ok(new_rope)
1388 } else if char_idx == self.len_chars() {
1389 Ok(Rope::new())
1391 } else {
1392 let mut new_rope = Rope {
1394 root: Arc::new(Arc::make_mut(&mut self.root).split(char_idx)),
1395 };
1396
1397 Arc::make_mut(&mut self.root).zip_fix_right();
1399 Arc::make_mut(&mut new_rope.root).zip_fix_left();
1400 self.pull_up_singular_nodes();
1401 new_rope.pull_up_singular_nodes();
1402
1403 Ok(new_rope)
1404 }
1405 } else {
1406 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1407 }
1408 }
1409
1410 #[inline]
1412 pub fn try_byte_to_char(&self, byte_idx: usize) -> Result<usize> {
1413 if byte_idx <= self.len_bytes() {
1415 let (chunk, b, c, _) = self.chunk_at_byte(byte_idx);
1416 Ok(c + byte_to_char_idx(chunk, byte_idx - b))
1417 } else {
1418 Err(Error::ByteIndexOutOfBounds(byte_idx, self.len_bytes()))
1419 }
1420 }
1421
1422 #[inline]
1424 pub fn try_byte_to_line(&self, byte_idx: usize) -> Result<usize> {
1425 if byte_idx <= self.len_bytes() {
1427 let (chunk, b, _, l) = self.chunk_at_byte(byte_idx);
1428 Ok(l + byte_to_line_idx(chunk, byte_idx - b))
1429 } else {
1430 Err(Error::ByteIndexOutOfBounds(byte_idx, self.len_bytes()))
1431 }
1432 }
1433
1434 #[inline]
1436 pub fn try_char_to_byte(&self, char_idx: usize) -> Result<usize> {
1437 if char_idx <= self.len_chars() {
1439 let (chunk, b, c, _) = self.chunk_at_char(char_idx);
1440 Ok(b + char_to_byte_idx(chunk, char_idx - c))
1441 } else {
1442 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1443 }
1444 }
1445
1446 #[inline]
1448 pub fn try_char_to_line(&self, char_idx: usize) -> Result<usize> {
1449 if char_idx <= self.len_chars() {
1451 let (chunk, _, c, l) = self.chunk_at_char(char_idx);
1452 Ok(l + char_to_line_idx(chunk, char_idx - c))
1453 } else {
1454 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1455 }
1456 }
1457
1458 #[inline]
1460 pub fn try_char_to_utf16_cu(&self, char_idx: usize) -> Result<usize> {
1461 if char_idx <= self.len_chars() {
1463 let (chunk, chunk_start_info) = self.root.get_chunk_at_char(char_idx);
1464 let chunk_byte_idx =
1465 char_to_byte_idx(chunk, char_idx - chunk_start_info.chars as usize);
1466 let surrogate_count = byte_to_utf16_surrogate_idx(chunk, chunk_byte_idx);
1467
1468 Ok(char_idx + chunk_start_info.utf16_surrogates as usize + surrogate_count)
1469 } else {
1470 Err(Error::CharIndexOutOfBounds(char_idx, self.len_chars()))
1471 }
1472 }
1473
1474 #[inline]
1476 pub fn try_utf16_cu_to_char(&self, utf16_cu_idx: usize) -> Result<usize> {
1477 if utf16_cu_idx <= self.len_utf16_cu() {
1479 let (chunk, chunk_start_info) = self.root.get_chunk_at_utf16_code_unit(utf16_cu_idx);
1480 let chunk_utf16_cu_idx = utf16_cu_idx
1481 - (chunk_start_info.chars + chunk_start_info.utf16_surrogates) as usize;
1482 let chunk_char_idx = utf16_code_unit_to_char_idx(chunk, chunk_utf16_cu_idx);
1483
1484 Ok(chunk_start_info.chars as usize + chunk_char_idx)
1485 } else {
1486 Err(Error::Utf16IndexOutOfBounds(
1487 utf16_cu_idx,
1488 self.len_utf16_cu(),
1489 ))
1490 }
1491 }
1492
1493 #[inline]
1495 pub fn try_line_to_byte(&self, line_idx: usize) -> Result<usize> {
1496 if line_idx <= self.len_lines() {
1498 if line_idx == self.len_lines() {
1499 Ok(self.len_bytes())
1500 } else {
1501 let (chunk, b, _, l) = self.chunk_at_line_break(line_idx);
1502 Ok(b + line_to_byte_idx(chunk, line_idx - l))
1503 }
1504 } else {
1505 Err(Error::LineIndexOutOfBounds(line_idx, self.len_lines()))
1506 }
1507 }
1508
1509 #[inline]
1511 pub fn try_line_to_char(&self, line_idx: usize) -> Result<usize> {
1512 if line_idx <= self.len_lines() {
1514 if line_idx == self.len_lines() {
1515 Ok(self.len_chars())
1516 } else {
1517 let (chunk, _, c, l) = self.chunk_at_line_break(line_idx);
1518 Ok(c + line_to_char_idx(chunk, line_idx - l))
1519 }
1520 } else {
1521 Err(Error::LineIndexOutOfBounds(line_idx, self.len_lines()))
1522 }
1523 }
1524
1525 #[inline]
1527 pub fn get_byte(&self, byte_idx: usize) -> Option<u8> {
1528 if byte_idx < self.len_bytes() {
1530 let (chunk, chunk_byte_idx, _, _) = self.chunk_at_byte(byte_idx);
1531 let chunk_rel_byte_idx = byte_idx - chunk_byte_idx;
1532 Some(chunk.as_bytes()[chunk_rel_byte_idx])
1533 } else {
1534 None
1535 }
1536 }
1537
1538 #[inline]
1540 pub fn get_char(&self, char_idx: usize) -> Option<char> {
1541 if char_idx < self.len_chars() {
1543 let (chunk, _, chunk_char_idx, _) = self.chunk_at_char(char_idx);
1544 let byte_idx = char_to_byte_idx(chunk, char_idx - chunk_char_idx);
1545 Some(chunk[byte_idx..].chars().next().unwrap())
1546 } else {
1547 None
1548 }
1549 }
1550
1551 #[inline]
1553 pub fn get_line(&self, line_idx: usize) -> Option<RopeSlice> {
1554 use crate::slice::RSEnum;
1555 use crate::str_utils::{count_chars, count_utf16_surrogates};
1556
1557 let len_lines = self.len_lines();
1558
1559 if line_idx < len_lines {
1561 let (chunk_1, _, c1, l1) = self.chunk_at_line_break(line_idx);
1562 let (chunk_2, _, c2, l2) = self.chunk_at_line_break(line_idx + 1);
1563 if c1 == c2 {
1564 let text1 = &chunk_1[line_to_byte_idx(chunk_1, line_idx - l1)..];
1565 let text2 = &text1[..line_to_byte_idx(text1, 1)];
1566 Some(RopeSlice(RSEnum::Light {
1567 text: text2,
1568 char_count: count_chars(text2) as Count,
1569 utf16_surrogate_count: count_utf16_surrogates(text2) as Count,
1570 line_break_count: if line_idx == (len_lines - 1) { 0 } else { 1 },
1571 }))
1572 } else {
1573 let start = c1 + line_to_char_idx(chunk_1, line_idx - l1);
1574 let end = c2 + line_to_char_idx(chunk_2, line_idx + 1 - l2);
1575 Some(self.slice(start..end))
1576 }
1577 } else {
1578 None
1579 }
1580 }
1581
1582 #[inline]
1584 pub fn get_chunk_at_byte(&self, byte_idx: usize) -> Option<(&str, usize, usize, usize)> {
1585 if byte_idx <= self.len_bytes() {
1587 let (chunk, info) = self.root.get_chunk_at_byte(byte_idx);
1588 Some((
1589 chunk,
1590 info.bytes as usize,
1591 info.chars as usize,
1592 info.line_breaks as usize,
1593 ))
1594 } else {
1595 None
1596 }
1597 }
1598
1599 #[inline]
1601 pub fn get_chunk_at_char(&self, char_idx: usize) -> Option<(&str, usize, usize, usize)> {
1602 if char_idx <= self.len_chars() {
1604 let (chunk, info) = self.root.get_chunk_at_char(char_idx);
1605 Some((
1606 chunk,
1607 info.bytes as usize,
1608 info.chars as usize,
1609 info.line_breaks as usize,
1610 ))
1611 } else {
1612 None
1613 }
1614 }
1615
1616 #[inline]
1618 pub fn get_chunk_at_line_break(
1619 &self,
1620 line_break_idx: usize,
1621 ) -> Option<(&str, usize, usize, usize)> {
1622 if line_break_idx <= self.len_lines() {
1624 let (chunk, info) = self.root.get_chunk_at_line_break(line_break_idx);
1625 Some((
1626 chunk,
1627 info.bytes as usize,
1628 info.chars as usize,
1629 info.line_breaks as usize,
1630 ))
1631 } else {
1632 None
1633 }
1634 }
1635
1636 #[inline]
1638 pub fn get_slice<R>(&self, char_range: R) -> Option<RopeSlice>
1639 where
1640 R: RangeBounds<usize>,
1641 {
1642 let start = start_bound_to_num(char_range.start_bound()).unwrap_or(0);
1643 let end = end_bound_to_num(char_range.end_bound()).unwrap_or_else(|| self.len_chars());
1644
1645 if start <= end && end <= self.len_chars() {
1647 Some(RopeSlice::new_with_range(&self.root, start, end))
1648 } else {
1649 None
1650 }
1651 }
1652
1653 #[inline]
1655 pub fn get_byte_slice<R>(&self, byte_range: R) -> Option<RopeSlice>
1656 where
1657 R: RangeBounds<usize>,
1658 {
1659 self.get_byte_slice_impl(byte_range).ok()
1660 }
1661
1662 pub(crate) fn get_byte_slice_impl<R>(&self, byte_range: R) -> Result<RopeSlice>
1663 where
1664 R: RangeBounds<usize>,
1665 {
1666 let start_range = start_bound_to_num(byte_range.start_bound());
1667 let end_range = end_bound_to_num(byte_range.end_bound());
1668
1669 match (start_range, end_range) {
1671 (Some(s), Some(e)) => {
1672 if s > e {
1673 return Err(Error::ByteRangeInvalid(s, e));
1674 } else if e > self.len_bytes() {
1675 return Err(Error::ByteRangeOutOfBounds(
1676 start_range,
1677 end_range,
1678 self.len_bytes(),
1679 ));
1680 }
1681 }
1682 (Some(s), None) => {
1683 if s > self.len_bytes() {
1684 return Err(Error::ByteRangeOutOfBounds(
1685 start_range,
1686 end_range,
1687 self.len_bytes(),
1688 ));
1689 }
1690 }
1691 (None, Some(e)) => {
1692 if e > self.len_bytes() {
1693 return Err(Error::ByteRangeOutOfBounds(
1694 start_range,
1695 end_range,
1696 self.len_bytes(),
1697 ));
1698 }
1699 }
1700 _ => {}
1701 }
1702
1703 let (start, end) = (
1704 start_range.unwrap_or(0),
1705 end_range.unwrap_or_else(|| self.len_bytes()),
1706 );
1707
1708 RopeSlice::new_with_byte_range(&self.root, start, end).map_err(|e| {
1709 if let Error::ByteRangeNotCharBoundary(_, _) = e {
1710 Error::ByteRangeNotCharBoundary(start_range, end_range)
1711 } else {
1712 e
1713 }
1714 })
1715 }
1716
1717 #[inline]
1719 pub fn get_bytes_at(&self, byte_idx: usize) -> Option<Bytes> {
1720 if byte_idx <= self.len_bytes() {
1722 let info = self.root.text_info();
1723 Some(Bytes::new_with_range_at(
1724 &self.root,
1725 byte_idx,
1726 (0, info.bytes as usize),
1727 (0, info.chars as usize),
1728 (0, info.line_breaks as usize + 1),
1729 ))
1730 } else {
1731 None
1732 }
1733 }
1734
1735 #[inline]
1737 pub fn get_chars_at(&self, char_idx: usize) -> Option<Chars> {
1738 if char_idx <= self.len_chars() {
1740 let info = self.root.text_info();
1741 Some(Chars::new_with_range_at(
1742 &self.root,
1743 char_idx,
1744 (0, info.bytes as usize),
1745 (0, info.chars as usize),
1746 (0, info.line_breaks as usize + 1),
1747 ))
1748 } else {
1749 None
1750 }
1751 }
1752
1753 #[inline]
1755 pub fn get_lines_at(&self, line_idx: usize) -> Option<Lines> {
1756 if line_idx <= self.len_lines() {
1758 Some(Lines::new_with_range_at(
1759 &self.root,
1760 line_idx,
1761 (0, self.len_bytes()),
1762 (0, self.len_lines()),
1763 ))
1764 } else {
1765 None
1766 }
1767 }
1768
1769 #[inline]
1771 pub fn get_chunks_at_byte(&self, byte_idx: usize) -> Option<(Chunks, usize, usize, usize)> {
1772 if byte_idx <= self.len_bytes() {
1774 Some(Chunks::new_with_range_at_byte(
1775 &self.root,
1776 byte_idx,
1777 (0, self.len_bytes()),
1778 (0, self.len_chars()),
1779 (0, self.len_lines()),
1780 ))
1781 } else {
1782 None
1783 }
1784 }
1785
1786 #[inline]
1788 pub fn get_chunks_at_char(&self, char_idx: usize) -> Option<(Chunks, usize, usize, usize)> {
1789 if char_idx <= self.len_chars() {
1791 Some(Chunks::new_with_range_at_char(
1792 &self.root,
1793 char_idx,
1794 (0, self.len_bytes()),
1795 (0, self.len_chars()),
1796 (0, self.len_lines()),
1797 ))
1798 } else {
1799 None
1800 }
1801 }
1802
1803 #[inline]
1805 pub fn get_chunks_at_line_break(
1806 &self,
1807 line_break_idx: usize,
1808 ) -> Option<(Chunks, usize, usize, usize)> {
1809 if line_break_idx <= self.len_lines() {
1811 Some(Chunks::new_with_range_at_line_break(
1812 &self.root,
1813 line_break_idx,
1814 (0, self.len_bytes()),
1815 (0, self.len_chars()),
1816 (0, self.len_lines()),
1817 ))
1818 } else {
1819 None
1820 }
1821 }
1822}
1823
1824impl<'a> From<&'a str> for Rope {
1828 #[inline]
1829 fn from(text: &'a str) -> Self {
1830 Rope::from_str(text)
1831 }
1832}
1833
1834impl<'a> From<std::borrow::Cow<'a, str>> for Rope {
1835 #[inline]
1836 fn from(text: std::borrow::Cow<'a, str>) -> Self {
1837 Rope::from_str(&text)
1838 }
1839}
1840
1841impl From<String> for Rope {
1842 #[inline]
1843 fn from(text: String) -> Self {
1844 Rope::from_str(&text)
1845 }
1846}
1847
1848impl<'a> From<RopeSlice<'a>> for Rope {
1852 fn from(s: RopeSlice<'a>) -> Self {
1853 use crate::slice::RSEnum;
1854 match s {
1855 RopeSlice(RSEnum::Full {
1856 node,
1857 start_info,
1858 end_info,
1859 }) => {
1860 let mut rope = Rope {
1861 root: Arc::clone(node),
1862 };
1863
1864 if end_info.chars < node.text_info().chars {
1866 {
1867 let root = Arc::make_mut(&mut rope.root);
1868 root.split(end_info.chars as usize);
1869 root.zip_fix_right();
1870 }
1871 rope.pull_up_singular_nodes();
1872 }
1873
1874 if start_info.chars > 0 {
1876 {
1877 let root = Arc::make_mut(&mut rope.root);
1878 *root = root.split(start_info.chars as usize);
1879 root.zip_fix_left();
1880 }
1881 rope.pull_up_singular_nodes();
1882 }
1883
1884 rope
1886 }
1887 RopeSlice(RSEnum::Light { text, .. }) => Rope::from_str(text),
1888 }
1889 }
1890}
1891
1892impl From<Rope> for String {
1893 #[inline]
1894 fn from(r: Rope) -> Self {
1895 String::from(&r)
1896 }
1897}
1898
1899impl<'a> From<&'a Rope> for String {
1900 #[inline]
1901 fn from(r: &'a Rope) -> Self {
1902 let mut text = String::with_capacity(r.len_bytes());
1903 text.extend(r.chunks());
1904 text
1905 }
1906}
1907
1908impl<'a> From<Rope> for std::borrow::Cow<'a, str> {
1909 #[inline]
1910 fn from(r: Rope) -> Self {
1911 std::borrow::Cow::Owned(String::from(r))
1912 }
1913}
1914
1915impl<'a> From<&'a Rope> for std::borrow::Cow<'a, str> {
1920 #[inline]
1921 fn from(r: &'a Rope) -> Self {
1922 if let Node::Leaf(ref text) = *r.root {
1923 std::borrow::Cow::Borrowed(text)
1924 } else {
1925 std::borrow::Cow::Owned(String::from(r))
1926 }
1927 }
1928}
1929
1930impl<'a> FromIterator<&'a str> for Rope {
1931 fn from_iter<T>(iter: T) -> Self
1932 where
1933 T: IntoIterator<Item = &'a str>,
1934 {
1935 let mut builder = RopeBuilder::new();
1936 for chunk in iter {
1937 builder.append(chunk);
1938 }
1939 builder.finish()
1940 }
1941}
1942
1943impl<'a> FromIterator<std::borrow::Cow<'a, str>> for Rope {
1944 fn from_iter<T>(iter: T) -> Self
1945 where
1946 T: IntoIterator<Item = std::borrow::Cow<'a, str>>,
1947 {
1948 let mut builder = RopeBuilder::new();
1949 for chunk in iter {
1950 builder.append(&chunk);
1951 }
1952 builder.finish()
1953 }
1954}
1955
1956impl FromIterator<String> for Rope {
1957 fn from_iter<T>(iter: T) -> Self
1958 where
1959 T: IntoIterator<Item = String>,
1960 {
1961 let mut builder = RopeBuilder::new();
1962 for chunk in iter {
1963 builder.append(&chunk);
1964 }
1965 builder.finish()
1966 }
1967}
1968
1969impl std::fmt::Debug for Rope {
1973 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1974 f.debug_list().entries(self.chunks()).finish()
1975 }
1976}
1977
1978impl std::fmt::Display for Rope {
1979 #[inline]
1980 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1981 for chunk in self.chunks() {
1982 write!(f, "{}", chunk)?
1983 }
1984 Ok(())
1985 }
1986}
1987
1988impl std::default::Default for Rope {
1989 #[inline]
1990 fn default() -> Self {
1991 Self::new()
1992 }
1993}
1994
1995impl std::cmp::Eq for Rope {}
1996
1997impl std::cmp::PartialEq<Rope> for Rope {
1998 #[inline]
1999 fn eq(&self, other: &Rope) -> bool {
2000 self.slice(..) == other.slice(..)
2001 }
2002}
2003
2004impl<'a> std::cmp::PartialEq<&'a str> for Rope {
2005 #[inline]
2006 fn eq(&self, other: &&'a str) -> bool {
2007 self.slice(..) == *other
2008 }
2009}
2010
2011impl<'a> std::cmp::PartialEq<Rope> for &'a str {
2012 #[inline]
2013 fn eq(&self, other: &Rope) -> bool {
2014 *self == other.slice(..)
2015 }
2016}
2017
2018impl std::cmp::PartialEq<str> for Rope {
2019 #[inline]
2020 fn eq(&self, other: &str) -> bool {
2021 self.slice(..) == other
2022 }
2023}
2024
2025impl std::cmp::PartialEq<Rope> for str {
2026 #[inline]
2027 fn eq(&self, other: &Rope) -> bool {
2028 self == other.slice(..)
2029 }
2030}
2031
2032impl std::cmp::PartialEq<String> for Rope {
2033 #[inline]
2034 fn eq(&self, other: &String) -> bool {
2035 self.slice(..) == other.as_str()
2036 }
2037}
2038
2039impl std::cmp::PartialEq<Rope> for String {
2040 #[inline]
2041 fn eq(&self, other: &Rope) -> bool {
2042 self.as_str() == other.slice(..)
2043 }
2044}
2045
2046impl<'a> std::cmp::PartialEq<std::borrow::Cow<'a, str>> for Rope {
2047 #[inline]
2048 fn eq(&self, other: &std::borrow::Cow<'a, str>) -> bool {
2049 self.slice(..) == **other
2050 }
2051}
2052
2053impl<'a> std::cmp::PartialEq<Rope> for std::borrow::Cow<'a, str> {
2054 #[inline]
2055 fn eq(&self, other: &Rope) -> bool {
2056 **self == other.slice(..)
2057 }
2058}
2059
2060impl std::cmp::Ord for Rope {
2061 #[inline]
2062 fn cmp(&self, other: &Rope) -> std::cmp::Ordering {
2063 self.slice(..).cmp(&other.slice(..))
2064 }
2065}
2066
2067impl std::cmp::PartialOrd<Rope> for Rope {
2068 #[inline]
2069 fn partial_cmp(&self, other: &Rope) -> Option<std::cmp::Ordering> {
2070 Some(self.cmp(other))
2071 }
2072}
2073
2074impl std::hash::Hash for Rope {
2075 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2076 self.slice(..).hash(state)
2077 }
2078}
2079
2080#[cfg(test)]
2083mod tests {
2084 use super::*;
2085 use crate::str_utils::*;
2086 use std::hash::{Hash, Hasher};
2087
2088 const TEXT: &str = "Hello there! How're you doing? It's \
2090 a fine day, isn't it? Aren't you glad \
2091 we're alive? こんにちは、みんなさん!";
2092 const TEXT_LINES: &str = "Hello there! How're you doing?\nIt's \
2094 a fine day, isn't it?\nAren't you glad \
2095 we're alive?\nこんにちは、みんなさん!";
2096 const TEXT_EMOJI: &str = "Hello there!🐸 How're you doing?🐸 It's \
2098 a fine day, isn't it?🐸 Aren't you glad \
2099 we're alive?🐸 こんにちは、みんなさん!";
2100
2101 #[test]
2102 fn new_01() {
2103 let r = Rope::new();
2104 assert_eq!(r, "");
2105
2106 r.assert_integrity();
2107 r.assert_invariants();
2108 }
2109
2110 #[test]
2111 fn from_str() {
2112 let r = Rope::from_str(TEXT);
2113 assert_eq!(r, TEXT);
2114
2115 r.assert_integrity();
2116 r.assert_invariants();
2117 }
2118
2119 #[test]
2120 fn len_bytes_01() {
2121 let r = Rope::from_str(TEXT);
2122 assert_eq!(r.len_bytes(), 127);
2123 }
2124
2125 #[test]
2126 fn len_bytes_02() {
2127 let r = Rope::from_str("");
2128 assert_eq!(r.len_bytes(), 0);
2129 }
2130
2131 #[test]
2132 fn len_chars_01() {
2133 let r = Rope::from_str(TEXT);
2134 assert_eq!(r.len_chars(), 103);
2135 }
2136
2137 #[test]
2138 fn len_chars_02() {
2139 let r = Rope::from_str("");
2140 assert_eq!(r.len_chars(), 0);
2141 }
2142
2143 #[test]
2144 fn len_lines_01() {
2145 let r = Rope::from_str(TEXT_LINES);
2146 assert_eq!(r.len_lines(), 4);
2147 }
2148
2149 #[test]
2150 fn len_lines_02() {
2151 let r = Rope::from_str("");
2152 assert_eq!(r.len_lines(), 1);
2153 }
2154
2155 #[test]
2156 fn len_utf16_cu_01() {
2157 let r = Rope::from_str(TEXT);
2158 assert_eq!(r.len_utf16_cu(), 103);
2159 }
2160
2161 #[test]
2162 fn len_utf16_cu_02() {
2163 let r = Rope::from_str(TEXT_EMOJI);
2164 assert_eq!(r.len_utf16_cu(), 111);
2165 }
2166
2167 #[test]
2168 fn len_utf16_cu_03() {
2169 let r = Rope::from_str("");
2170 assert_eq!(r.len_utf16_cu(), 0);
2171 }
2172
2173 #[test]
2174 fn insert_01() {
2175 let mut r = Rope::from_str(TEXT);
2176 r.insert(3, "AA");
2177
2178 assert_eq!(
2179 r,
2180 "HelAAlo there! How're you doing? It's \
2181 a fine day, isn't it? Aren't you glad \
2182 we're alive? こんにちは、みんなさん!"
2183 );
2184
2185 r.assert_integrity();
2186 r.assert_invariants();
2187 }
2188
2189 #[test]
2190 fn insert_02() {
2191 let mut r = Rope::from_str(TEXT);
2192 r.insert(0, "AA");
2193
2194 assert_eq!(
2195 r,
2196 "AAHello there! How're you doing? It's \
2197 a fine day, isn't it? Aren't you glad \
2198 we're alive? こんにちは、みんなさん!"
2199 );
2200
2201 r.assert_integrity();
2202 r.assert_invariants();
2203 }
2204
2205 #[test]
2206 fn insert_03() {
2207 let mut r = Rope::from_str(TEXT);
2208 r.insert(103, "AA");
2209
2210 assert_eq!(
2211 r,
2212 "Hello there! How're you doing? It's \
2213 a fine day, isn't it? Aren't you glad \
2214 we're alive? こんにちは、みんなさん!AA"
2215 );
2216
2217 r.assert_integrity();
2218 r.assert_invariants();
2219 }
2220
2221 #[test]
2222 fn insert_04() {
2223 let mut r = Rope::new();
2224 r.insert(0, "He");
2225 r.insert(2, "l");
2226 r.insert(3, "l");
2227 r.insert(4, "o w");
2228 r.insert(7, "o");
2229 r.insert(8, "rl");
2230 r.insert(10, "d!");
2231 r.insert(3, "zopter");
2232
2233 assert_eq!("Helzopterlo world!", r);
2234
2235 r.assert_integrity();
2236 r.assert_invariants();
2237 }
2238
2239 #[test]
2240 fn insert_05() {
2241 let mut r = Rope::new();
2242 r.insert(0, "こんいちは、みんなさん!");
2243 r.insert(7, "zopter");
2244 assert_eq!("こんいちは、みzopterんなさん!", r);
2245
2246 r.assert_integrity();
2247 r.assert_invariants();
2248 }
2249
2250 #[test]
2251 fn insert_06() {
2252 let mut r = Rope::new();
2253 r.insert(0, "こ");
2254 r.insert(1, "ん");
2255 r.insert(2, "い");
2256 r.insert(3, "ち");
2257 r.insert(4, "は");
2258 r.insert(5, "、");
2259 r.insert(6, "み");
2260 r.insert(7, "ん");
2261 r.insert(8, "な");
2262 r.insert(9, "さ");
2263 r.insert(10, "ん");
2264 r.insert(11, "!");
2265 r.insert(7, "zopter");
2266 assert_eq!("こんいちは、みzopterんなさん!", r);
2267
2268 r.assert_integrity();
2269 r.assert_invariants();
2270 }
2271
2272 #[test]
2273 fn insert_char_01() {
2274 let mut r = Rope::from_str(TEXT);
2275 r.insert_char(3, 'A');
2276 r.insert_char(12, '!');
2277 r.insert_char(12, '!');
2278
2279 assert_eq!(
2280 r,
2281 "HelAlo there!!! How're you doing? It's \
2282 a fine day, isn't it? Aren't you glad \
2283 we're alive? こんにちは、みんなさん!"
2284 );
2285
2286 r.assert_integrity();
2287 r.assert_invariants();
2288 }
2289
2290 #[test]
2291 fn insert_char_02() {
2292 let mut r = Rope::new();
2293
2294 r.insert_char(0, '!');
2295 r.insert_char(0, 'こ');
2296 r.insert_char(1, 'ん');
2297 r.insert_char(2, 'い');
2298 r.insert_char(3, 'ち');
2299 r.insert_char(4, 'は');
2300 r.insert_char(5, '、');
2301 r.insert_char(6, 'み');
2302 r.insert_char(7, 'ん');
2303 r.insert_char(8, 'な');
2304 r.insert_char(9, 'さ');
2305 r.insert_char(10, 'ん');
2306 assert_eq!("こんいちは、みんなさん!", r);
2307
2308 r.assert_integrity();
2309 r.assert_invariants();
2310 }
2311
2312 #[test]
2313 fn remove_01() {
2314 let mut r = Rope::from_str(TEXT);
2315
2316 r.remove(5..11);
2317 r.remove(24..31);
2318 r.remove(19..25);
2319 r.remove(75..79);
2320 assert_eq!(
2321 r,
2322 "Hello! How're you \
2323 a fine day, isn't it? Aren't you glad \
2324 we're alive? こんにんなさん!"
2325 );
2326
2327 r.assert_integrity();
2328 r.assert_invariants();
2329 }
2330
2331 #[test]
2332 fn remove_02() {
2333 let mut r = Rope::from_str("\r\n\r\n\r\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
2334
2335 r.remove(3..6);
2338 assert_eq!(r, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
2339
2340 r.assert_integrity();
2341 r.assert_invariants();
2342 }
2343
2344 #[test]
2345 fn remove_03() {
2346 let mut r = Rope::from_str(TEXT);
2347
2348 r.remove(45..45);
2350 assert_eq!(r, TEXT);
2351
2352 r.assert_integrity();
2353 r.assert_invariants();
2354 }
2355
2356 #[test]
2357 fn remove_04() {
2358 let mut r = Rope::from_str(TEXT);
2359
2360 r.remove(0..103);
2362 assert_eq!(r, "");
2363
2364 r.assert_integrity();
2365 r.assert_invariants();
2366 }
2367
2368 #[test]
2369 fn remove_05() {
2370 let mut r = Rope::from_str(TEXT);
2371
2372 r.remove(3..100);
2374 assert_eq!(r, "Helさん!");
2375
2376 r.assert_integrity();
2377 r.assert_invariants();
2378 }
2379
2380 #[test]
2381 #[should_panic]
2382 fn remove_06() {
2383 let mut r = Rope::from_str(TEXT);
2384 #[allow(clippy::reversed_empty_ranges)]
2385 r.remove(56..55); }
2387
2388 #[test]
2389 #[should_panic]
2390 fn remove_07() {
2391 let mut r = Rope::from_str(TEXT);
2392 r.remove(102..104); }
2394
2395 #[test]
2396 #[should_panic]
2397 fn remove_08() {
2398 let mut r = Rope::from_str(TEXT);
2399 r.remove(103..104); }
2401
2402 #[test]
2403 #[should_panic]
2404 fn remove_09() {
2405 let mut r = Rope::from_str(TEXT);
2406 r.remove(104..104); }
2408
2409 #[test]
2410 #[should_panic]
2411 fn remove_10() {
2412 let mut r = Rope::from_str(TEXT);
2413 r.remove(104..105); }
2415
2416 #[test]
2417 fn split_off_01() {
2418 let mut r = Rope::from_str(TEXT);
2419
2420 let r2 = r.split_off(50);
2421 assert_eq!(
2422 r,
2423 "Hello there! How're you doing? It's \
2424 a fine day, "
2425 );
2426 assert_eq!(
2427 r2,
2428 "isn't it? Aren't you glad \
2429 we're alive? こんにちは、みんなさん!"
2430 );
2431
2432 r.assert_integrity();
2433 r2.assert_integrity();
2434 r.assert_invariants();
2435 r2.assert_invariants();
2436 }
2437
2438 #[test]
2439 fn split_off_02() {
2440 let mut r = Rope::from_str(TEXT);
2441
2442 let r2 = r.split_off(1);
2443 assert_eq!(r, "H");
2444 assert_eq!(
2445 r2,
2446 "ello there! How're you doing? It's \
2447 a fine day, isn't it? Aren't you glad \
2448 we're alive? こんにちは、みんなさん!"
2449 );
2450
2451 r.assert_integrity();
2452 r2.assert_integrity();
2453 r.assert_invariants();
2454 r2.assert_invariants();
2455 }
2456
2457 #[test]
2458 fn split_off_03() {
2459 let mut r = Rope::from_str(TEXT);
2460
2461 let r2 = r.split_off(102);
2462 assert_eq!(
2463 r,
2464 "Hello there! How're you doing? It's \
2465 a fine day, isn't it? Aren't you glad \
2466 we're alive? こんにちは、みんなさん"
2467 );
2468 assert_eq!(r2, "!");
2469
2470 r.assert_integrity();
2471 r2.assert_integrity();
2472 r.assert_invariants();
2473 r2.assert_invariants();
2474 }
2475
2476 #[test]
2477 fn split_off_04() {
2478 let mut r = Rope::from_str(TEXT);
2479
2480 let r2 = r.split_off(0);
2481 assert_eq!(r, "");
2482 assert_eq!(
2483 r2,
2484 "Hello there! How're you doing? It's \
2485 a fine day, isn't it? Aren't you glad \
2486 we're alive? こんにちは、みんなさん!"
2487 );
2488
2489 r.assert_integrity();
2490 r2.assert_integrity();
2491 r.assert_invariants();
2492 r2.assert_invariants();
2493 }
2494
2495 #[test]
2496 fn split_off_05() {
2497 let mut r = Rope::from_str(TEXT);
2498
2499 let r2 = r.split_off(103);
2500 assert_eq!(
2501 r,
2502 "Hello there! How're you doing? It's \
2503 a fine day, isn't it? Aren't you glad \
2504 we're alive? こんにちは、みんなさん!"
2505 );
2506 assert_eq!(r2, "");
2507
2508 r.assert_integrity();
2509 r2.assert_integrity();
2510 r.assert_invariants();
2511 r2.assert_invariants();
2512 }
2513
2514 #[test]
2515 #[should_panic]
2516 fn split_off_06() {
2517 let mut r = Rope::from_str(TEXT);
2518 r.split_off(104); }
2520
2521 #[test]
2522 fn append_01() {
2523 let mut r = Rope::from_str(
2524 "Hello there! How're you doing? It's \
2525 a fine day, isn't ",
2526 );
2527 let r2 = Rope::from_str(
2528 "it? Aren't you glad \
2529 we're alive? こんにちは、みんなさん!",
2530 );
2531
2532 r.append(r2);
2533 assert_eq!(r, TEXT);
2534
2535 r.assert_integrity();
2536 r.assert_invariants();
2537 }
2538
2539 #[test]
2540 fn append_02() {
2541 let mut r = Rope::from_str(
2542 "Hello there! How're you doing? It's \
2543 a fine day, isn't it? Aren't you glad \
2544 we're alive? こんに",
2545 );
2546 let r2 = Rope::from_str("ちは、みんなさん!");
2547
2548 r.append(r2);
2549 assert_eq!(r, TEXT);
2550
2551 r.assert_integrity();
2552 r.assert_invariants();
2553 }
2554
2555 #[test]
2556 fn append_03() {
2557 let mut r = Rope::from_str(
2558 "Hello there! How're you doing? It's \
2559 a fine day, isn't it? Aren't you glad \
2560 we're alive? こんにちは、みんなさん",
2561 );
2562 let r2 = Rope::from_str("!");
2563
2564 r.append(r2);
2565 assert_eq!(r, TEXT);
2566
2567 r.assert_integrity();
2568 r.assert_invariants();
2569 }
2570
2571 #[test]
2572 fn append_04() {
2573 let mut r = Rope::from_str("H");
2574 let r2 = Rope::from_str(
2575 "ello there! How're you doing? It's \
2576 a fine day, isn't it? Aren't you glad \
2577 we're alive? こんにちは、みんなさん!",
2578 );
2579
2580 r.append(r2);
2581 assert_eq!(r, TEXT);
2582
2583 r.assert_integrity();
2584 r.assert_invariants();
2585 }
2586
2587 #[test]
2588 fn append_05() {
2589 let mut r = Rope::from_str(TEXT);
2590 let r2 = Rope::from_str("");
2591
2592 r.append(r2);
2593 assert_eq!(r, TEXT);
2594
2595 r.assert_integrity();
2596 r.assert_invariants();
2597 }
2598
2599 #[test]
2600 fn append_06() {
2601 let mut r = Rope::from_str("");
2602 let r2 = Rope::from_str(TEXT);
2603
2604 r.append(r2);
2605 assert_eq!(r, TEXT);
2606
2607 r.assert_integrity();
2608 r.assert_invariants();
2609 }
2610
2611 #[test]
2612 fn append_07() {
2613 let mut 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");
2614 let r2 = Rope::from_str("\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r");
2615
2616 r.append(r2);
2617 let s2 = r.to_string();
2618 assert_eq!(r, "\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\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r");
2619 assert_eq!(r.len_lines(), byte_to_line_idx(&s2, s2.len()) + 1);
2620
2621 r.assert_integrity();
2622 r.assert_invariants();
2623 }
2624
2625 #[test]
2626 fn shrink_to_fit_01() {
2627 let mut r = Rope::new();
2628 for _ in 0..10 {
2629 let len = r.len_chars();
2630 r.insert(len / 2, "こ");
2631 r.insert(len / 2, "ん");
2632 r.insert(len / 2, "い");
2633 r.insert(len / 2, "ち");
2634 r.insert(len / 2, "は");
2635 r.insert(len / 2, "、");
2636 r.insert(len / 2, "み");
2637 r.insert(len / 2, "ん");
2638 r.insert(len / 2, "な");
2639 r.insert(len / 2, "さ");
2640 r.insert(len / 2, "ん");
2641 r.insert(len / 2, "!");
2642 r.insert(len / 2, "zopter");
2643 }
2644
2645 let r2 = r.clone();
2646 r.shrink_to_fit();
2647
2648 assert_eq!(r, r2);
2649
2650 r.assert_integrity();
2651 r.assert_invariants();
2652 }
2653
2654 #[test]
2655 fn byte_to_char_01() {
2656 let r = Rope::from_str(TEXT);
2657
2658 assert_eq!(0, r.byte_to_char(0));
2659 assert_eq!(1, r.byte_to_char(1));
2660 assert_eq!(2, r.byte_to_char(2));
2661
2662 assert_eq!(91, r.byte_to_char(91));
2663 assert_eq!(91, r.byte_to_char(92));
2664 assert_eq!(91, r.byte_to_char(93));
2665
2666 assert_eq!(92, r.byte_to_char(94));
2667 assert_eq!(92, r.byte_to_char(95));
2668 assert_eq!(92, r.byte_to_char(96));
2669
2670 assert_eq!(102, r.byte_to_char(124));
2671 assert_eq!(102, r.byte_to_char(125));
2672 assert_eq!(102, r.byte_to_char(126));
2673 assert_eq!(103, r.byte_to_char(127));
2674 }
2675
2676 #[test]
2677 fn byte_to_line_01() {
2678 let r = Rope::from_str(TEXT_LINES);
2679
2680 assert_eq!(0, r.byte_to_line(0));
2681 assert_eq!(0, r.byte_to_line(1));
2682
2683 assert_eq!(0, r.byte_to_line(31));
2684 assert_eq!(1, r.byte_to_line(32));
2685 assert_eq!(1, r.byte_to_line(33));
2686
2687 assert_eq!(1, r.byte_to_line(58));
2688 assert_eq!(2, r.byte_to_line(59));
2689 assert_eq!(2, r.byte_to_line(60));
2690
2691 assert_eq!(2, r.byte_to_line(87));
2692 assert_eq!(3, r.byte_to_line(88));
2693 assert_eq!(3, r.byte_to_line(89));
2694 assert_eq!(3, r.byte_to_line(124));
2695 }
2696
2697 #[test]
2698 fn byte_to_line_02() {
2699 let r = Rope::from_str("");
2700 assert_eq!(0, r.byte_to_line(0));
2701 }
2702
2703 #[test]
2704 fn byte_to_line_03() {
2705 let r = Rope::from_str("Hi there\n");
2706 assert_eq!(0, r.byte_to_line(0));
2707 assert_eq!(0, r.byte_to_line(8));
2708 assert_eq!(1, r.byte_to_line(9));
2709 }
2710
2711 #[test]
2712 #[should_panic]
2713 fn byte_to_line_04() {
2714 let r = Rope::from_str(TEXT_LINES);
2715 r.byte_to_line(125);
2716 }
2717
2718 #[test]
2719 fn char_to_byte_01() {
2720 let r = Rope::from_str(TEXT);
2721
2722 assert_eq!(0, r.char_to_byte(0));
2723 assert_eq!(1, r.char_to_byte(1));
2724 assert_eq!(2, r.char_to_byte(2));
2725
2726 assert_eq!(91, r.char_to_byte(91));
2727 assert_eq!(94, r.char_to_byte(92));
2728 assert_eq!(97, r.char_to_byte(93));
2729 assert_eq!(100, r.char_to_byte(94));
2730
2731 assert_eq!(124, r.char_to_byte(102));
2732 assert_eq!(127, r.char_to_byte(103));
2733 }
2734
2735 #[test]
2736 fn char_to_line_01() {
2737 let r = Rope::from_str(TEXT_LINES);
2738
2739 assert_eq!(0, r.char_to_line(0));
2740 assert_eq!(0, r.char_to_line(1));
2741
2742 assert_eq!(0, r.char_to_line(31));
2743 assert_eq!(1, r.char_to_line(32));
2744 assert_eq!(1, r.char_to_line(33));
2745
2746 assert_eq!(1, r.char_to_line(58));
2747 assert_eq!(2, r.char_to_line(59));
2748 assert_eq!(2, r.char_to_line(60));
2749
2750 assert_eq!(2, r.char_to_line(87));
2751 assert_eq!(3, r.char_to_line(88));
2752 assert_eq!(3, r.char_to_line(89));
2753 assert_eq!(3, r.char_to_line(100));
2754 }
2755
2756 #[test]
2757 fn char_to_line_02() {
2758 let r = Rope::from_str("");
2759 assert_eq!(0, r.char_to_line(0));
2760 }
2761
2762 #[test]
2763 fn char_to_line_03() {
2764 let r = Rope::from_str("Hi there\n");
2765 assert_eq!(0, r.char_to_line(0));
2766 assert_eq!(0, r.char_to_line(8));
2767 assert_eq!(1, r.char_to_line(9));
2768 }
2769
2770 #[test]
2771 #[should_panic]
2772 fn char_to_line_04() {
2773 let r = Rope::from_str(TEXT_LINES);
2774 r.char_to_line(101);
2775 }
2776
2777 #[test]
2778 fn line_to_byte_01() {
2779 let r = Rope::from_str(TEXT_LINES);
2780
2781 assert_eq!(0, r.line_to_byte(0));
2782 assert_eq!(32, r.line_to_byte(1));
2783 assert_eq!(59, r.line_to_byte(2));
2784 assert_eq!(88, r.line_to_byte(3));
2785 assert_eq!(124, r.line_to_byte(4));
2786 }
2787
2788 #[test]
2789 fn line_to_byte_02() {
2790 let r = Rope::from_str("");
2791 assert_eq!(0, r.line_to_byte(0));
2792 assert_eq!(0, r.line_to_byte(1));
2793 }
2794
2795 #[test]
2796 #[should_panic]
2797 fn line_to_byte_03() {
2798 let r = Rope::from_str(TEXT_LINES);
2799 r.line_to_byte(5);
2800 }
2801
2802 #[test]
2803 fn line_to_char_01() {
2804 let r = Rope::from_str(TEXT_LINES);
2805
2806 assert_eq!(0, r.line_to_char(0));
2807 assert_eq!(32, r.line_to_char(1));
2808 assert_eq!(59, r.line_to_char(2));
2809 assert_eq!(88, r.line_to_char(3));
2810 assert_eq!(100, r.line_to_char(4));
2811 }
2812
2813 #[test]
2814 fn line_to_char_02() {
2815 let r = Rope::from_str("");
2816 assert_eq!(0, r.line_to_char(0));
2817 assert_eq!(0, r.line_to_char(1));
2818 }
2819
2820 #[test]
2821 #[should_panic]
2822 fn line_to_char_03() {
2823 let r = Rope::from_str(TEXT_LINES);
2824 r.line_to_char(5);
2825 }
2826
2827 #[test]
2828 fn char_to_utf16_cu_01() {
2829 let r = Rope::from_str("");
2830 assert_eq!(0, r.char_to_utf16_cu(0));
2831 }
2832
2833 #[test]
2834 #[should_panic]
2835 fn char_to_utf16_cu_02() {
2836 let r = Rope::from_str("");
2837 r.char_to_utf16_cu(1);
2838 }
2839
2840 #[test]
2841 fn char_to_utf16_cu_03() {
2842 let r = Rope::from_str(TEXT_EMOJI);
2843
2844 assert_eq!(0, r.char_to_utf16_cu(0));
2845
2846 assert_eq!(12, r.char_to_utf16_cu(12));
2847 assert_eq!(14, r.char_to_utf16_cu(13));
2848
2849 assert_eq!(33, r.char_to_utf16_cu(32));
2850 assert_eq!(35, r.char_to_utf16_cu(33));
2851
2852 assert_eq!(63, r.char_to_utf16_cu(61));
2853 assert_eq!(65, r.char_to_utf16_cu(62));
2854
2855 assert_eq!(95, r.char_to_utf16_cu(92));
2856 assert_eq!(97, r.char_to_utf16_cu(93));
2857
2858 assert_eq!(111, r.char_to_utf16_cu(107));
2859 }
2860
2861 #[test]
2862 #[should_panic]
2863 fn char_to_utf16_cu_04() {
2864 let r = Rope::from_str(TEXT_EMOJI);
2865 r.char_to_utf16_cu(108);
2866 }
2867
2868 #[test]
2869 fn utf16_cu_to_char_01() {
2870 let r = Rope::from_str("");
2871 assert_eq!(0, r.utf16_cu_to_char(0));
2872 }
2873
2874 #[test]
2875 #[should_panic]
2876 fn utf16_cu_to_char_02() {
2877 let r = Rope::from_str("");
2878 r.utf16_cu_to_char(1);
2879 }
2880
2881 #[test]
2882 fn utf16_cu_to_char_03() {
2883 let r = Rope::from_str(TEXT_EMOJI);
2884
2885 assert_eq!(0, r.utf16_cu_to_char(0));
2886
2887 assert_eq!(12, r.utf16_cu_to_char(12));
2888 assert_eq!(12, r.utf16_cu_to_char(13));
2889 assert_eq!(13, r.utf16_cu_to_char(14));
2890
2891 assert_eq!(32, r.utf16_cu_to_char(33));
2892 assert_eq!(32, r.utf16_cu_to_char(34));
2893 assert_eq!(33, r.utf16_cu_to_char(35));
2894
2895 assert_eq!(61, r.utf16_cu_to_char(63));
2896 assert_eq!(61, r.utf16_cu_to_char(64));
2897 assert_eq!(62, r.utf16_cu_to_char(65));
2898
2899 assert_eq!(92, r.utf16_cu_to_char(95));
2900 assert_eq!(92, r.utf16_cu_to_char(96));
2901 assert_eq!(93, r.utf16_cu_to_char(97));
2902
2903 assert_eq!(107, r.utf16_cu_to_char(111));
2904 }
2905
2906 #[test]
2907 #[should_panic]
2908 fn utf16_cu_to_char_04() {
2909 let r = Rope::from_str(TEXT_EMOJI);
2910 r.utf16_cu_to_char(112);
2911 }
2912
2913 #[test]
2914 fn byte_01() {
2915 let r = Rope::from_str(TEXT);
2916
2917 assert_eq!(r.byte(0), b'H');
2918
2919 assert_eq!(r.byte(124), 0xEF);
2921 assert_eq!(r.byte(125), 0xBC);
2922 assert_eq!(r.byte(126), 0x81);
2923 }
2924
2925 #[test]
2926 #[should_panic]
2927 fn byte_02() {
2928 let r = Rope::from_str(TEXT);
2929 r.byte(127);
2930 }
2931
2932 #[test]
2933 #[should_panic]
2934 fn byte_03() {
2935 let r = Rope::from_str("");
2936 r.byte(0);
2937 }
2938
2939 #[test]
2940 fn char_01() {
2941 let r = Rope::from_str(TEXT);
2942
2943 assert_eq!(r.char(0), 'H');
2944 assert_eq!(r.char(10), 'e');
2945 assert_eq!(r.char(18), 'r');
2946 assert_eq!(r.char(102), '!');
2947 }
2948
2949 #[test]
2950 #[should_panic]
2951 fn char_02() {
2952 let r = Rope::from_str(TEXT);
2953 r.char(103);
2954 }
2955
2956 #[test]
2957 #[should_panic]
2958 fn char_03() {
2959 let r = Rope::from_str("");
2960 r.char(0);
2961 }
2962
2963 #[test]
2964 fn line_01() {
2965 let r = Rope::from_str(TEXT_LINES);
2966
2967 let l0 = r.line(0);
2968 assert_eq!(l0, "Hello there! How're you doing?\n");
2969 assert_eq!(l0.len_bytes(), 32);
2970 assert_eq!(l0.len_chars(), 32);
2971 assert_eq!(l0.len_lines(), 2);
2972
2973 let l1 = r.line(1);
2974 assert_eq!(l1, "It's a fine day, isn't it?\n");
2975 assert_eq!(l1.len_bytes(), 27);
2976 assert_eq!(l1.len_chars(), 27);
2977 assert_eq!(l1.len_lines(), 2);
2978
2979 let l2 = r.line(2);
2980 assert_eq!(l2, "Aren't you glad we're alive?\n");
2981 assert_eq!(l2.len_bytes(), 29);
2982 assert_eq!(l2.len_chars(), 29);
2983 assert_eq!(l2.len_lines(), 2);
2984
2985 let l3 = r.line(3);
2986 assert_eq!(l3, "こんにちは、みんなさん!");
2987 assert_eq!(l3.len_bytes(), 36);
2988 assert_eq!(l3.len_chars(), 12);
2989 assert_eq!(l3.len_lines(), 1);
2990 }
2991
2992 #[test]
2993 fn line_02() {
2994 let r = Rope::from_str("Hello there! How're you doing?\n");
2995
2996 assert_eq!(r.line(0), "Hello there! How're you doing?\n");
2997 assert_eq!(r.line(1), "");
2998 }
2999
3000 #[test]
3001 fn line_03() {
3002 let r = Rope::from_str("Hi\nHi\nHi\nHi\nHi\nHi\n");
3003
3004 assert_eq!(r.line(0), "Hi\n");
3005 assert_eq!(r.line(1), "Hi\n");
3006 assert_eq!(r.line(2), "Hi\n");
3007 assert_eq!(r.line(3), "Hi\n");
3008 assert_eq!(r.line(4), "Hi\n");
3009 assert_eq!(r.line(5), "Hi\n");
3010 assert_eq!(r.line(6), "");
3011 }
3012
3013 #[test]
3014 fn line_04() {
3015 let r = Rope::from_str("");
3016
3017 assert_eq!(r.line(0), "");
3018 }
3019
3020 #[test]
3021 #[should_panic]
3022 fn line_05() {
3023 let r = Rope::from_str(TEXT_LINES);
3024 r.line(4);
3025 }
3026
3027 #[test]
3028 fn line_06() {
3029 let r = Rope::from_str("1\n2\n3\n4\n5\n6\n7\n8");
3030
3031 assert_eq!(r.line(0).len_lines(), 2);
3032 assert_eq!(r.line(1).len_lines(), 2);
3033 assert_eq!(r.line(2).len_lines(), 2);
3034 assert_eq!(r.line(3).len_lines(), 2);
3035 assert_eq!(r.line(4).len_lines(), 2);
3036 assert_eq!(r.line(5).len_lines(), 2);
3037 assert_eq!(r.line(6).len_lines(), 2);
3038 assert_eq!(r.line(7).len_lines(), 1);
3039 }
3040
3041 #[test]
3042 fn chunk_at_byte() {
3043 let r = Rope::from_str(TEXT_LINES);
3044 let mut t = TEXT_LINES;
3045
3046 let mut last_chunk = "";
3047 for i in 0..r.len_bytes() {
3048 let (chunk, b, c, l) = r.chunk_at_byte(i);
3049 assert_eq!(c, byte_to_char_idx(TEXT_LINES, b));
3050 assert_eq!(l, byte_to_line_idx(TEXT_LINES, b));
3051 if chunk != last_chunk {
3052 assert_eq!(chunk, &t[..chunk.len()]);
3053 t = &t[chunk.len()..];
3054 last_chunk = chunk;
3055 }
3056
3057 let c1 = {
3058 let i2 = byte_to_char_idx(TEXT_LINES, i);
3059 TEXT_LINES.chars().nth(i2).unwrap()
3060 };
3061 let c2 = {
3062 let i2 = i - b;
3063 let i3 = byte_to_char_idx(chunk, i2);
3064 chunk.chars().nth(i3).unwrap()
3065 };
3066 assert_eq!(c1, c2);
3067 }
3068 assert_eq!(t.len(), 0);
3069 }
3070
3071 #[test]
3072 fn chunk_at_char() {
3073 let r = Rope::from_str(TEXT_LINES);
3074 let mut t = TEXT_LINES;
3075
3076 let mut last_chunk = "";
3077 for i in 0..r.len_chars() {
3078 let (chunk, b, c, l) = r.chunk_at_char(i);
3079 assert_eq!(b, char_to_byte_idx(TEXT_LINES, c));
3080 assert_eq!(l, char_to_line_idx(TEXT_LINES, c));
3081 if chunk != last_chunk {
3082 assert_eq!(chunk, &t[..chunk.len()]);
3083 t = &t[chunk.len()..];
3084 last_chunk = chunk;
3085 }
3086
3087 let c1 = TEXT_LINES.chars().nth(i).unwrap();
3088 let c2 = {
3089 let i2 = i - c;
3090 chunk.chars().nth(i2).unwrap()
3091 };
3092 assert_eq!(c1, c2);
3093 }
3094 assert_eq!(t.len(), 0);
3095 }
3096
3097 #[test]
3098 fn chunk_at_line_break() {
3099 let r = Rope::from_str(TEXT_LINES);
3100
3101 {
3103 let (chunk, b, c, l) = r.chunk_at_line_break(0);
3104 assert_eq!(chunk, &TEXT_LINES[..chunk.len()]);
3105 assert_eq!(b, 0);
3106 assert_eq!(c, 0);
3107 assert_eq!(l, 0);
3108 }
3109
3110 for i in 1..r.len_lines() {
3112 let (chunk, b, c, l) = r.chunk_at_line_break(i);
3113 assert_eq!(chunk, &TEXT_LINES[b..(b + chunk.len())]);
3114 assert_eq!(c, byte_to_char_idx(TEXT_LINES, b));
3115 assert_eq!(l, byte_to_line_idx(TEXT_LINES, b));
3116 assert!(l < i);
3117 assert!(i <= byte_to_line_idx(TEXT_LINES, b + chunk.len()));
3118 }
3119
3120 {
3122 let (chunk, b, c, l) = r.chunk_at_line_break(r.len_lines());
3123 assert_eq!(chunk, &TEXT_LINES[(TEXT_LINES.len() - chunk.len())..]);
3124 assert_eq!(chunk, &TEXT_LINES[b..]);
3125 assert_eq!(c, byte_to_char_idx(TEXT_LINES, b));
3126 assert_eq!(l, byte_to_line_idx(TEXT_LINES, b));
3127 }
3128 }
3129
3130 #[test]
3131 fn slice_01() {
3132 let r = Rope::from_str(TEXT);
3133
3134 let s = r.slice(0..r.len_chars());
3135
3136 assert_eq!(TEXT, s);
3137 }
3138
3139 #[test]
3140 fn slice_02() {
3141 let r = Rope::from_str(TEXT);
3142
3143 let s = r.slice(5..21);
3144
3145 assert_eq!(&TEXT[5..21], s);
3146 }
3147
3148 #[test]
3149 fn slice_03() {
3150 let r = Rope::from_str(TEXT);
3151
3152 let s = r.slice(31..97);
3153
3154 assert_eq!(&TEXT[31..109], s);
3155 }
3156
3157 #[test]
3158 fn slice_04() {
3159 let r = Rope::from_str(TEXT);
3160
3161 let s = r.slice(53..53);
3162
3163 assert_eq!("", s);
3164 }
3165
3166 #[test]
3167 #[should_panic]
3168 fn slice_05() {
3169 let r = Rope::from_str(TEXT);
3170 #[allow(clippy::reversed_empty_ranges)]
3171 r.slice(53..52); }
3173
3174 #[test]
3175 #[should_panic]
3176 fn slice_06() {
3177 let r = Rope::from_str(TEXT);
3178 r.slice(102..104);
3179 }
3180
3181 #[test]
3182 fn byte_slice_01() {
3183 let r = Rope::from_str(TEXT);
3184
3185 let s = r.byte_slice(0..r.len_bytes());
3186
3187 assert_eq!(TEXT, s);
3188 }
3189
3190 #[test]
3191 fn byte_slice_02() {
3192 let r = Rope::from_str(TEXT);
3193
3194 let s = r.byte_slice(5..21);
3195
3196 assert_eq!(&TEXT[5..21], s);
3197 }
3198
3199 #[test]
3200 fn byte_slice_03() {
3201 let r = Rope::from_str(TEXT);
3202
3203 let s = r.byte_slice(31..97);
3204
3205 assert_eq!(&TEXT[31..97], s);
3206 }
3207
3208 #[test]
3209 fn byte_slice_04() {
3210 let r = Rope::from_str(TEXT);
3211
3212 let s = r.byte_slice(53..53);
3213
3214 assert_eq!("", s);
3215 }
3216
3217 #[test]
3218 #[should_panic]
3219 fn byte_slice_05() {
3220 let r = Rope::from_str(TEXT);
3221 #[allow(clippy::reversed_empty_ranges)]
3222 r.byte_slice(53..52); }
3224
3225 #[test]
3226 #[should_panic]
3227 fn byte_slice_06() {
3228 let r = Rope::from_str(TEXT);
3229 r.byte_slice(20..128);
3230 }
3231
3232 #[test]
3233 #[should_panic]
3234 fn byte_slice_07() {
3235 let r = Rope::from_str(TEXT);
3236 r.byte_slice(..96);
3238 }
3239
3240 #[test]
3241 #[should_panic]
3242 fn byte_slice_08() {
3243 let r = Rope::from_str(TEXT);
3244 r.byte_slice(96..);
3246 }
3247
3248 #[test]
3249 fn eq_rope_01() {
3250 let r = Rope::from_str("");
3251
3252 assert_eq!(r, r);
3253 }
3254
3255 #[test]
3256 fn eq_rope_02() {
3257 let r = Rope::from_str(TEXT);
3258
3259 assert_eq!(r, r);
3260 }
3261
3262 #[test]
3263 fn eq_rope_03() {
3264 let r1 = Rope::from_str(TEXT);
3265 let mut r2 = r1.clone();
3266 r2.remove(26..27);
3267 r2.insert(26, "z");
3268
3269 assert_ne!(r1, r2);
3270 }
3271
3272 #[test]
3273 fn eq_rope_04() {
3274 let r = Rope::from_str("");
3275
3276 assert_eq!(r, "");
3277 assert_eq!("", r);
3278 }
3279
3280 #[test]
3281 fn eq_rope_05() {
3282 let r = Rope::from_str(TEXT);
3283
3284 assert_eq!(r, TEXT);
3285 assert_eq!(TEXT, r);
3286 }
3287
3288 #[test]
3289 fn eq_rope_06() {
3290 let mut r = Rope::from_str(TEXT);
3291 r.remove(26..27);
3292 r.insert(26, "z");
3293
3294 assert_ne!(r, TEXT);
3295 assert_ne!(TEXT, r);
3296 }
3297
3298 #[test]
3299 fn eq_rope_07() {
3300 let r = Rope::from_str(TEXT);
3301 let s: String = TEXT.into();
3302
3303 assert_eq!(r, s);
3304 assert_eq!(s, r);
3305 }
3306
3307 #[test]
3308 fn to_string_01() {
3309 let r = Rope::from_str(TEXT);
3310 let s: String = (&r).into();
3311
3312 assert_eq!(r, s);
3313 }
3314
3315 #[test]
3316 fn to_cow_01() {
3317 use std::borrow::Cow;
3318 let r = Rope::from_str(TEXT);
3319 let cow: Cow<str> = (&r).into();
3320
3321 assert_eq!(r, cow);
3322 }
3323
3324 #[test]
3325 fn to_cow_02() {
3326 use std::borrow::Cow;
3327 let r = Rope::from_str(TEXT);
3328 let cow: Cow<str> = (r.clone()).into();
3329
3330 assert_eq!(r, cow);
3331 }
3332
3333 #[test]
3334 fn to_cow_03() {
3335 use std::borrow::Cow;
3336 let r = Rope::from_str("a");
3337 let cow: Cow<str> = (&r).into();
3338
3339 if let Cow::Owned(_) = cow {
3341 panic!("Small Cow conversions should result in a borrow.");
3342 }
3343
3344 assert_eq!(r, cow);
3345 }
3346
3347 #[test]
3348 fn from_rope_slice_01() {
3349 let r1 = Rope::from_str(TEXT);
3350 let s = r1.slice(..);
3351 let r2: Rope = s.into();
3352
3353 assert_eq!(r1, r2);
3354 assert_eq!(s, r2);
3355 }
3356
3357 #[test]
3358 fn from_rope_slice_02() {
3359 let r1 = Rope::from_str(TEXT);
3360 let s = r1.slice(0..24);
3361 let r2: Rope = s.into();
3362
3363 assert_eq!(s, r2);
3364 }
3365
3366 #[test]
3367 fn from_rope_slice_03() {
3368 let r1 = Rope::from_str(TEXT);
3369 let s = r1.slice(13..89);
3370 let r2: Rope = s.into();
3371
3372 assert_eq!(s, r2);
3373 }
3374
3375 #[test]
3376 fn from_rope_slice_04() {
3377 let r1 = Rope::from_str(TEXT);
3378 let s = r1.slice(13..41);
3379 let r2: Rope = s.into();
3380
3381 assert_eq!(s, r2);
3382 }
3383
3384 #[test]
3385 fn from_iter_01() {
3386 let r1 = Rope::from_str(TEXT);
3387 let r2: Rope = Rope::from_iter(r1.chunks());
3388
3389 assert_eq!(r1, r2);
3390 }
3391
3392 #[test]
3393 fn hash_01() {
3394 let mut h1 = std::collections::hash_map::DefaultHasher::new();
3395 let mut h2 = std::collections::hash_map::DefaultHasher::new();
3396 let r1 = Rope::from_str("Hello there!");
3397 let mut r2 = Rope::from_str("Hlotee");
3398 r2.insert_char(3, ' ');
3399 r2.insert_char(7, '!');
3400 r2.insert_char(1, 'e');
3401 r2.insert_char(3, 'l');
3402 r2.insert_char(7, 'h');
3403 r2.insert_char(9, 'r');
3404
3405 r1.hash(&mut h1);
3406 r2.hash(&mut h2);
3407
3408 assert_eq!(h1.finish(), h2.finish());
3409 }
3410
3411 #[test]
3412 fn hash_02() {
3413 let mut h1 = std::collections::hash_map::DefaultHasher::new();
3414 let mut h2 = std::collections::hash_map::DefaultHasher::new();
3415 let r1 = Rope::from_str("Hello there!");
3416 let r2 = Rope::from_str("Hello there.");
3417
3418 r1.hash(&mut h1);
3419 r2.hash(&mut h2);
3420
3421 assert_ne!(h1.finish(), h2.finish());
3422 }
3423
3424 #[test]
3425 fn hash_03() {
3426 let mut h1 = std::collections::hash_map::DefaultHasher::new();
3427 let mut h2 = std::collections::hash_map::DefaultHasher::new();
3428 let r = Rope::from_str("Hello there!");
3429 let s = [Rope::from_str("Hello "), Rope::from_str("there!")];
3430
3431 r.hash(&mut h1);
3432 Rope::hash_slice(&s, &mut h2);
3433
3434 assert_ne!(h1.finish(), h2.finish());
3435 }
3436
3437 #[test]
3438 fn is_instance_01() {
3439 let r = Rope::from_str("Hello there!");
3440 let mut c1 = r.clone();
3441 let c2 = c1.clone();
3442
3443 assert!(r.is_instance(&c1));
3444 assert!(r.is_instance(&c2));
3445 assert!(c1.is_instance(&c2));
3446
3447 c1.insert(0, "Oh! ");
3448
3449 assert!(!r.is_instance(&c1));
3450 assert!(r.is_instance(&c2));
3451 assert!(!c1.is_instance(&c2));
3452 }
3453
3454 }