ropey/
rope.rs

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/// A utf8 text rope.
18///
19/// The time complexity of nearly all edit and query operations on `Rope` are
20/// worst-case `O(log N)` in the length of the rope.  `Rope` is designed to
21/// work efficiently even for huge (in the gigabytes) and pathological (all on
22/// one line) texts.
23///
24/// # Editing Operations
25///
26/// The primary editing operations on `Rope` are insertion and removal of text.
27/// For example:
28///
29/// ```
30/// # use ropey::Rope;
31/// #
32/// let mut rope = Rope::from_str("Hello みんなさん!");
33/// rope.remove(6..11);
34/// rope.insert(6, "world");
35///
36/// assert_eq!(rope, "Hello world!");
37/// ```
38///
39/// # Query Operations
40///
41/// `Rope` provides a rich set of efficient query functions, including querying
42/// rope length in bytes/`char`s/lines, fetching individual `char`s or lines,
43/// and converting between byte/`char`/line indices.  For example, to find the
44/// starting `char` index of a given line:
45///
46/// ```
47/// # use ropey::Rope;
48/// #
49/// let rope = Rope::from_str("Hello みんなさん!\nHow are you?\nThis text has multiple lines!");
50///
51/// assert_eq!(rope.line_to_char(0), 0);
52/// assert_eq!(rope.line_to_char(1), 13);
53/// assert_eq!(rope.line_to_char(2), 26);
54/// ```
55///
56/// # Slicing
57///
58/// You can take immutable slices of a `Rope` using `slice()`:
59///
60/// ```
61/// # use ropey::Rope;
62/// #
63/// let mut rope = Rope::from_str("Hello みんなさん!");
64/// let middle = rope.slice(3..8);
65///
66/// assert_eq!(middle, "lo みん");
67/// ```
68///
69/// # Cloning
70///
71/// Cloning `Rope`s is extremely cheap, running in `O(1)` time and taking a
72/// small constant amount of memory for the new clone, regardless of text size.
73/// This is accomplished by data sharing between `Rope` clones.  The memory
74/// used by clones only grows incrementally as the their contents diverge due
75/// to edits.  All of this is thread safe, so clones can be sent freely
76/// between threads.
77///
78/// The primary intended use-case for this feature is to allow asynchronous
79/// processing of `Rope`s.  For example, saving a large document to disk in a
80/// separate thread while the user continues to perform edits.
81#[derive(Clone)]
82pub struct Rope {
83    pub(crate) root: Arc<Node>,
84}
85
86impl Rope {
87    //-----------------------------------------------------------------------
88    // Constructors
89
90    /// Creates an empty `Rope`.
91    #[inline]
92    pub fn new() -> Self {
93        Rope {
94            root: Arc::new(Node::new()),
95        }
96    }
97
98    /// Creates a `Rope` from a string slice.
99    ///
100    /// Runs in O(N) time.
101    #[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    /// Creates a `Rope` from the output of a reader.
108    ///
109    /// This is a convenience function, and provides *no specific guarantees*
110    /// about performance or internal implementation aside from the runtime
111    /// complexity listed below.
112    ///
113    /// When more precise control over IO behavior, buffering, etc. is desired,
114    /// you should handle IO yourself and use [`RopeBuilder`] to build the
115    /// `Rope`.
116    ///
117    /// Runs in O(N) time.
118    ///
119    /// # Errors
120    ///
121    /// - If the reader returns an error, `from_reader` stops and returns
122    ///   that error.
123    /// - If non-utf8 data is encountered, an IO error with kind
124    ///   `InvalidData` is returned.
125    ///
126    /// Note: some data from the reader is likely consumed even if there is
127    /// an error.
128    #[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; // How much `buffer` is currently filled with valid data
134        loop {
135            match reader.read(&mut buffer[fill_idx..]) {
136                Ok(read_count) => {
137                    fill_idx += read_count;
138
139                    // Determine how much of the buffer is valid utf8.
140                    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                    // Append the valid part of the buffer to the rope.
146                    if valid_count > 0 {
147                        // The unsafe block here is reinterpreting the bytes as
148                        // utf8.  This is safe because the bytes being
149                        // reinterpreted have already been validated as utf8
150                        // just above.
151                        builder.append(unsafe {
152                            std::str::from_utf8_unchecked(&buffer[..valid_count])
153                        });
154                    }
155
156                    // Shift the un-read part of the buffer to the beginning.
157                    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                        // Buffer is full and none of it could be consumed.  Utf8
164                        // codepoints don't get that large, so it's clearly not
165                        // valid text.
166                        return Err(io::Error::new(
167                            io::ErrorKind::InvalidData,
168                            "stream did not contain valid UTF-8",
169                        ));
170                    }
171
172                    // If we're done reading
173                    if read_count == 0 {
174                        if fill_idx > 0 {
175                            // We couldn't consume all data.
176                            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                    // Read error
188                    return Err(e);
189                }
190            }
191        }
192    }
193
194    //-----------------------------------------------------------------------
195    // Convenience output methods
196
197    /// Writes the contents of the `Rope` to a writer.
198    ///
199    /// This is a convenience function, and provides *no specific guarantees*
200    /// about performance or internal implementation aside from the runtime
201    /// complexity listed below.
202    ///
203    /// When more precise control over IO behavior, buffering, etc. is
204    /// desired, you should handle IO yourself and use the [`Chunks`]
205    /// iterator to iterate through the `Rope`'s contents.
206    ///
207    /// Runs in O(N) time.
208    ///
209    /// # Errors
210    ///
211    /// - If the writer returns an error, `write_to` stops and returns that
212    ///   error.
213    ///
214    /// Note: some data may have been written even if an error is returned.
215    #[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    //-----------------------------------------------------------------------
225    // Informational methods
226
227    /// Total number of bytes in the `Rope`.
228    ///
229    /// Runs in O(1) time.
230    #[inline]
231    pub fn len_bytes(&self) -> usize {
232        self.root.byte_count()
233    }
234
235    /// Total number of chars in the `Rope`.
236    ///
237    /// Runs in O(1) time.
238    #[inline]
239    pub fn len_chars(&self) -> usize {
240        self.root.char_count()
241    }
242
243    /// Total number of lines in the `Rope`.
244    ///
245    /// Runs in O(1) time.
246    #[inline]
247    pub fn len_lines(&self) -> usize {
248        self.root.line_break_count() + 1
249    }
250
251    /// Total number of utf16 code units that would be in `Rope` if it were
252    /// encoded as utf16.
253    ///
254    /// Ropey stores text internally as utf8, but sometimes it is necessary
255    /// to interact with external APIs that still use utf16.  This function is
256    /// primarily intended for such situations, and is otherwise not very
257    /// useful.
258    ///
259    /// Runs in O(1) time.
260    #[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    //-----------------------------------------------------------------------
267    // Memory management methods
268
269    /// Total size of the `Rope`'s text buffer space, in bytes.
270    ///
271    /// This includes unoccupied text buffer space.  You can calculate
272    /// the unoccupied space with `capacity() - len_bytes()`.  In general,
273    /// there will always be some unoccupied buffer space.
274    ///
275    /// Runs in O(N) time.
276    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    /// Shrinks the `Rope`'s capacity to the minimum possible.
285    ///
286    /// This will rarely result in `capacity() == len_bytes()`.  `Rope`
287    /// stores text in a sequence of fixed-capacity chunks, so an exact fit
288    /// only happens for texts that are both a precise multiple of that
289    /// capacity _and_ have code point boundaries that line up exactly with
290    /// the capacity boundaries.
291    ///
292    /// After calling this, the difference between `capacity()` and
293    /// `len_bytes()` is typically under 1KB per megabyte of text in the
294    /// `Rope`.
295    ///
296    /// **NOTE:** calling this on a `Rope` clone causes it to stop sharing
297    /// all data with its other clones.  In such cases you will very likely
298    /// be _increasing_ total memory usage despite shrinking the `Rope`'s
299    /// capacity.
300    ///
301    /// Runs in O(N) time, and uses O(log N) additional space during
302    /// shrinking.
303    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    //-----------------------------------------------------------------------
332    // Edit methods
333
334    /// Inserts `text` at char index `char_idx`.
335    ///
336    /// Runs in O(M + log N) time, where N is the length of the `Rope` and M
337    /// is the length of `text`.
338    ///
339    /// # Panics
340    ///
341    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
342    #[inline]
343    pub fn insert(&mut self, char_idx: usize, text: &str) {
344        // Bounds check
345        self.try_insert(char_idx, text).unwrap()
346    }
347
348    /// Inserts a single char `ch` at char index `char_idx`.
349    ///
350    /// Runs in O(log N) time.
351    ///
352    /// # Panics
353    ///
354    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
355    #[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    /// Private internal-only method that does a single insertion of
361    /// sufficiently small text.
362    ///
363    /// This only works correctly for insertion texts smaller than or equal to
364    /// `MAX_BYTES - 4`.
365    ///
366    /// Note that a lot of the complexity in this method comes from avoiding
367    /// splitting CRLF pairs and, when possible, avoiding re-scanning text for
368    /// text info.  It is otherwise conceptually fairly straightforward.
369    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                // First check if we have a left seam.
379                if idx == 0 && char_idx > 0 && ins_text.as_bytes()[0] == 0x0A {
380                    left_seam = true;
381                    ins_text = &ins_text[1..];
382                    // Early out if it was only an LF.
383                    if ins_text.is_empty() {
384                        return (cur_info, None);
385                    }
386                }
387
388                // Find our byte index
389                let byte_idx = char_to_byte_idx(leaf_text, idx);
390
391                // No node splitting
392                if (leaf_text.len() + ins_text.len()) <= MAX_BYTES {
393                    // Calculate new info without doing a full re-scan of cur_text.
394                    let new_info = {
395                        // Get summed info of current text and to-be-inserted text.
396                        #[allow(unused_mut)]
397                        let mut info = cur_info + TextInfo::from_str(ins_text);
398                        // Check for CRLF pairs on the insertion seams, and
399                        // adjust line break counts accordingly.
400                        #[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                    // Insert the text and return the new info
425                    leaf_text.insert_str(byte_idx, ins_text);
426                    (new_info, None)
427                }
428                // We're splitting the node
429                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                        // Leaf couldn't be validly split, so leave it oversized
440                        (l_text_info, None)
441                    }
442                }
443            },
444        );
445
446        // Handle root splitting, if any.
447        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        // Insert the LF to the left.
459        // TODO: this code feels fairly redundant with above.  Can we DRY this
460        // better?
461        if left_seam {
462            // Do the insertion
463            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                    // No node splitting
471                    if (leaf_text.len() + ins_text.len()) <= MAX_BYTES {
472                        // Calculate new info without doing a full re-scan of cur_text
473                        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                        // Insert the text and return the new info
485                        leaf_text.insert_str(byte_idx, "\n");
486                        (new_info, None)
487                    }
488                    // We're splitting the node
489                    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                            // Leaf couldn't be validly split, so leave it oversized
500                            (l_text_info, None)
501                        }
502                    }
503                },
504            );
505
506            // Handle root splitting, if any.
507            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    /// Removes the text in the given char index range.
521    ///
522    /// Uses range syntax, e.g. `2..7`, `2..`, etc.  The range is in `char`
523    /// indices.
524    ///
525    /// Runs in O(M + log N) time, where N is the length of the `Rope` and M
526    /// is the length of the range being removed.
527    ///
528    /// # Example
529    ///
530    /// ```
531    /// # use ropey::Rope;
532    /// let mut rope = Rope::from_str("Hello world!");
533    /// rope.remove(5..);
534    ///
535    /// assert_eq!("Hello", rope);
536    /// ```
537    ///
538    /// # Panics
539    ///
540    /// Panics if the start of the range is greater than the end, or if the
541    /// end is out of bounds (i.e. `end > len_chars()`).
542    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    /// Splits the `Rope` at `char_idx`, returning the right part of
550    /// the split.
551    ///
552    /// Runs in O(log N) time.
553    ///
554    /// # Panics
555    ///
556    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
557    pub fn split_off(&mut self, char_idx: usize) -> Self {
558        self.try_split_off(char_idx).unwrap()
559    }
560
561    /// Appends a `Rope` to the end of this one, consuming the other `Rope`.
562    ///
563    /// Runs in O(log N) time.
564    pub fn append(&mut self, other: Self) {
565        if self.len_chars() == 0 {
566            // Special case
567            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            // Fix up any mess left behind.
605            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    //-----------------------------------------------------------------------
617    // Index conversion methods
618
619    /// Returns the char index of the given byte.
620    ///
621    /// Notes:
622    ///
623    /// - If the byte is in the middle of a multi-byte char, returns the
624    ///   index of the char that the byte belongs to.
625    /// - `byte_idx` can be one-past-the-end, which will return
626    ///   one-past-the-end char index.
627    ///
628    /// Runs in O(log N) time.
629    ///
630    /// # Panics
631    ///
632    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx > len_bytes()`).
633    #[inline]
634    pub fn byte_to_char(&self, byte_idx: usize) -> usize {
635        self.try_byte_to_char(byte_idx).unwrap()
636    }
637
638    /// Returns the line index of the given byte.
639    ///
640    /// Notes:
641    ///
642    /// - Lines are zero-indexed.  This is functionally equivalent to
643    ///   counting the line endings before the specified byte.
644    /// - `byte_idx` can be one-past-the-end, which will return the
645    ///   last line index.
646    ///
647    /// Runs in O(log N) time.
648    ///
649    /// # Panics
650    ///
651    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx > len_bytes()`).
652    #[inline]
653    pub fn byte_to_line(&self, byte_idx: usize) -> usize {
654        self.try_byte_to_line(byte_idx).unwrap()
655    }
656
657    /// Returns the byte index of the given char.
658    ///
659    /// Notes:
660    ///
661    /// - `char_idx` can be one-past-the-end, which will return
662    ///   one-past-the-end byte index.
663    ///
664    /// Runs in O(log N) time.
665    ///
666    /// # Panics
667    ///
668    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
669    #[inline]
670    pub fn char_to_byte(&self, char_idx: usize) -> usize {
671        self.try_char_to_byte(char_idx).unwrap()
672    }
673
674    /// Returns the line index of the given char.
675    ///
676    /// Notes:
677    ///
678    /// - Lines are zero-indexed.  This is functionally equivalent to
679    ///   counting the line endings before the specified char.
680    /// - `char_idx` can be one-past-the-end, which will return the
681    ///   last line index.
682    ///
683    /// Runs in O(log N) time.
684    ///
685    /// # Panics
686    ///
687    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
688    #[inline]
689    pub fn char_to_line(&self, char_idx: usize) -> usize {
690        self.try_char_to_line(char_idx).unwrap()
691    }
692
693    /// Returns the utf16 code unit index of the given char.
694    ///
695    /// Ropey stores text internally as utf8, but sometimes it is necessary
696    /// to interact with external APIs that still use utf16.  This function is
697    /// primarily intended for such situations, and is otherwise not very
698    /// useful.
699    ///
700    /// Runs in O(log N) time.
701    ///
702    /// # Panics
703    ///
704    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
705    #[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    /// Returns the char index of the given utf16 code unit.
711    ///
712    /// Ropey stores text internally as utf8, but sometimes it is necessary
713    /// to interact with external APIs that still use utf16.  This function is
714    /// primarily intended for such situations, and is otherwise not very
715    /// useful.
716    ///
717    /// Note: if the utf16 code unit is in the middle of a char, returns the
718    /// index of the char that it belongs to.
719    ///
720    /// Runs in O(log N) time.
721    ///
722    /// # Panics
723    ///
724    /// Panics if `utf16_cu_idx` is out of bounds
725    /// (i.e. `utf16_cu_idx > len_utf16_cu()`).
726    #[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    /// Returns the byte index of the start of the given line.
732    ///
733    /// Notes:
734    ///
735    /// - Lines are zero-indexed.
736    /// - `line_idx` can be one-past-the-end, which will return
737    ///   one-past-the-end byte index.
738    ///
739    /// Runs in O(log N) time.
740    ///
741    /// # Panics
742    ///
743    /// Panics if `line_idx` is out of bounds (i.e. `line_idx > len_lines()`).
744    #[inline]
745    pub fn line_to_byte(&self, line_idx: usize) -> usize {
746        self.try_line_to_byte(line_idx).unwrap()
747    }
748
749    /// Returns the char index of the start of the given line.
750    ///
751    /// Notes:
752    ///
753    /// - Lines are zero-indexed.
754    /// - `line_idx` can be one-past-the-end, which will return
755    ///   one-past-the-end char index.
756    ///
757    /// Runs in O(log N) time.
758    ///
759    /// # Panics
760    ///
761    /// Panics if `line_idx` is out of bounds (i.e. `line_idx > len_lines()`).
762    #[inline]
763    pub fn line_to_char(&self, line_idx: usize) -> usize {
764        self.try_line_to_char(line_idx).unwrap()
765    }
766
767    //-----------------------------------------------------------------------
768    // Fetch methods
769
770    /// Returns the byte at `byte_idx`.
771    ///
772    /// Runs in O(log N) time.
773    ///
774    /// # Panics
775    ///
776    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx >= len_bytes()`).
777    #[inline]
778    pub fn byte(&self, byte_idx: usize) -> u8 {
779        // Bounds check
780        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    /// Returns the char at `char_idx`.
792    ///
793    /// Runs in O(log N) time.
794    ///
795    /// # Panics
796    ///
797    /// Panics if `char_idx` is out of bounds (i.e. `char_idx >= len_chars()`).
798    #[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    /// Returns the line at `line_idx`.
812    ///
813    /// Note: lines are zero-indexed.
814    ///
815    /// Runs in O(log N) time.
816    ///
817    /// # Panics
818    ///
819    /// Panics if `line_idx` is out of bounds (i.e. `line_idx >= len_lines()`).
820    #[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    /// Returns the chunk containing the given byte index.
834    ///
835    /// Also returns the byte and char indices of the beginning of the chunk
836    /// and the index of the line that the chunk starts on.
837    ///
838    /// Note: for convenience, a one-past-the-end `byte_idx` returns the last
839    /// chunk of the `RopeSlice`.
840    ///
841    /// The return value is organized as
842    /// `(chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
843    ///
844    /// Runs in O(log N) time.
845    ///
846    /// # Panics
847    ///
848    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx > len_bytes()`).
849    #[inline]
850    pub fn chunk_at_byte(&self, byte_idx: usize) -> (&str, usize, usize, usize) {
851        // Bounds check
852        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    /// Returns the chunk containing the given char index.
864    ///
865    /// Also returns the byte and char indices of the beginning of the chunk
866    /// and the index of the line that the chunk starts on.
867    ///
868    /// Note: for convenience, a one-past-the-end `char_idx` returns the last
869    /// chunk of the `RopeSlice`.
870    ///
871    /// The return value is organized as
872    /// `(chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
873    ///
874    /// Runs in O(log N) time.
875    ///
876    /// # Panics
877    ///
878    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
879    #[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    /// Returns the chunk containing the given line break.
893    ///
894    /// Also returns the byte and char indices of the beginning of the chunk
895    /// and the index of the line that the chunk starts on.
896    ///
897    /// Note: for convenience, both the beginning and end of the rope are
898    /// considered line breaks for the purposes of indexing.  For example, in
899    /// the string `"Hello \n world!"` 0 would give the first chunk, 1 would
900    /// give the chunk containing the newline character, and 2 would give the
901    /// last chunk.
902    ///
903    /// The return value is organized as
904    /// `(chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
905    ///
906    /// Runs in O(log N) time.
907    ///
908    /// # Panics
909    ///
910    /// Panics if `line_break_idx` is out of bounds (i.e. `line_break_idx > len_lines()`).
911    #[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    //-----------------------------------------------------------------------
925    // Slicing
926
927    /// Gets an immutable slice of the `Rope`, using char indices.
928    ///
929    /// Uses range syntax, e.g. `2..7`, `2..`, etc.
930    ///
931    /// # Example
932    ///
933    /// ```
934    /// # use ropey::Rope;
935    /// let rope = Rope::from_str("Hello world!");
936    /// let slice = rope.slice(..5);
937    ///
938    /// assert_eq!("Hello", slice);
939    /// ```
940    ///
941    /// Runs in O(log N) time.
942    ///
943    /// # Panics
944    ///
945    /// Panics if the start of the range is greater than the end, or if the
946    /// end is out of bounds (i.e. `end > len_chars()`).
947    #[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    /// Gets and immutable slice of the `Rope`, using byte indices.
956    ///
957    /// Uses range syntax, e.g. `2..7`, `2..`, etc.
958    ///
959    /// Runs in O(log N) time.
960    ///
961    /// # Panics
962    ///
963    /// Panics if:
964    /// - The start of the range is greater than the end.
965    /// - The end is out of bounds (i.e. `end > len_bytes()`).
966    /// - The range doesn't align with char boundaries.
967    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    //-----------------------------------------------------------------------
978    // Iterator methods
979
980    /// Creates an iterator over the bytes of the `Rope`.
981    ///
982    /// Runs in O(log N) time.
983    #[inline]
984    pub fn bytes(&self) -> Bytes {
985        Bytes::new(&self.root)
986    }
987
988    /// Creates an iterator over the bytes of the `Rope`, starting at byte
989    /// `byte_idx`.
990    ///
991    /// If `byte_idx == len_bytes()` then an iterator at the end of the
992    /// `Rope` is created (i.e. `next()` will return `None`).
993    ///
994    /// Runs in O(log N) time.
995    ///
996    /// # Panics
997    ///
998    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx > len_bytes()`).
999    #[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    /// Creates an iterator over the chars of the `Rope`.
1013    ///
1014    /// Runs in O(log N) time.
1015    #[inline]
1016    pub fn chars(&self) -> Chars {
1017        Chars::new(&self.root)
1018    }
1019
1020    /// Creates an iterator over the chars of the `Rope`, starting at char
1021    /// `char_idx`.
1022    ///
1023    /// If `char_idx == len_chars()` then an iterator at the end of the
1024    /// `Rope` is created (i.e. `next()` will return `None`).
1025    ///
1026    /// Runs in O(log N) time.
1027    ///
1028    /// # Panics
1029    ///
1030    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
1031    #[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    /// Creates an iterator over the lines of the `Rope`.
1045    ///
1046    /// Runs in O(log N) time.
1047    #[inline]
1048    pub fn lines(&self) -> Lines {
1049        Lines::new(&self.root)
1050    }
1051
1052    /// Creates an iterator over the lines of the `Rope`, starting at line
1053    /// `line_idx`.
1054    ///
1055    /// If `line_idx == len_lines()` then an iterator at the end of the
1056    /// `Rope` is created (i.e. `next()` will return `None`).
1057    ///
1058    /// Runs in O(log N) time.
1059    ///
1060    /// # Panics
1061    ///
1062    /// Panics if `line_idx` is out of bounds (i.e. `line_idx > len_lines()`).
1063    #[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    /// Creates an iterator over the chunks of the `Rope`.
1077    ///
1078    /// Runs in O(log N) time.
1079    #[inline]
1080    pub fn chunks(&self) -> Chunks {
1081        Chunks::new(&self.root)
1082    }
1083
1084    /// Creates an iterator over the chunks of the `Rope`, with the
1085    /// iterator starting at the chunk containing `byte_idx`.
1086    ///
1087    /// Also returns the byte and char indices of the beginning of the first
1088    /// chunk to be yielded, and the index of the line that chunk starts on.
1089    ///
1090    /// If `byte_idx == len_bytes()` an iterator at the end of the `Rope`
1091    /// (yielding `None` on a call to `next()`) is created.
1092    ///
1093    /// The return value is organized as
1094    /// `(iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
1095    ///
1096    /// Runs in O(log N) time.
1097    ///
1098    /// # Panics
1099    ///
1100    /// Panics if `byte_idx` is out of bounds (i.e. `byte_idx > len_bytes()`).
1101    #[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    /// Creates an iterator over the chunks of the `Rope`, with the
1115    /// iterator starting at the chunk containing `char_idx`.
1116    ///
1117    /// Also returns the byte and char indices of the beginning of the first
1118    /// chunk to be yielded, and the index of the line that chunk starts on.
1119    ///
1120    /// If `char_idx == len_chars()` an iterator at the end of the `Rope`
1121    /// (yielding `None` on a call to `next()`) is created.
1122    ///
1123    /// The return value is organized as
1124    /// `(iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
1125    ///
1126    /// Runs in O(log N) time.
1127    ///
1128    /// # Panics
1129    ///
1130    /// Panics if `char_idx` is out of bounds (i.e. `char_idx > len_chars()`).
1131    #[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    /// Creates an iterator over the chunks of the `Rope`, with the
1145    /// iterator starting at the chunk containing `line_break_idx`.
1146    ///
1147    /// Also returns the byte and char indices of the beginning of the first
1148    /// chunk to be yielded, and the index of the line that chunk starts on.
1149    ///
1150    /// Note: for convenience, both the beginning and end of the `Rope` are
1151    /// considered line breaks for the purposes of indexing.  For example, in
1152    /// the string `"Hello \n world!"` 0 would create an iterator starting on
1153    /// the first chunk, 1 would create an iterator starting on the chunk
1154    /// containing the newline character, and 2 would create an iterator at
1155    /// the end of the `Rope` (yielding `None` on a call to `next()`).
1156    ///
1157    /// The return value is organized as
1158    /// `(iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx)`.
1159    ///
1160    /// Runs in O(log N) time.
1161    ///
1162    /// # Panics
1163    ///
1164    /// Panics if `line_break_idx` is out of bounds (i.e. `line_break_idx > len_lines()`).
1165    #[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    /// Returns true if this rope and `other` point to precisely the same
1179    /// in-memory data.
1180    ///
1181    /// This happens when one of the ropes is a clone of the other and
1182    /// neither have been modified since then.  Because clones initially
1183    /// share all the same data, it can be useful to check if they still
1184    /// point to precisely the same memory as a way of determining
1185    /// whether they are both still unmodified.
1186    ///
1187    /// Note: this is distinct from checking for equality: two ropes can
1188    /// have the same *contents* (equal) but be stored in different
1189    /// memory locations (not instances).  Importantly, two clones that
1190    /// post-cloning are modified identically will *not* be instances
1191    /// anymore, even though they will have equal contents.
1192    ///
1193    /// Runs in O(1) time.
1194    #[inline]
1195    pub fn is_instance(&self, other: &Rope) -> bool {
1196        Arc::ptr_eq(&self.root, &other.root)
1197    }
1198
1199    //-----------------------------------------------------------------------
1200    // Debugging
1201
1202    /// NOT PART OF THE PUBLIC API (hidden from docs for a reason!)
1203    ///
1204    /// Debugging tool to make sure that all of the meta-data of the
1205    /// tree is consistent with the actual data.
1206    #[doc(hidden)]
1207    pub fn assert_integrity(&self) {
1208        self.root.assert_integrity();
1209    }
1210
1211    /// NOT PART OF THE PUBLIC API (hidden from docs for a reason!)
1212    ///
1213    /// Debugging tool to make sure that all of the following invariants
1214    /// hold true throughout the tree:
1215    ///
1216    /// - The tree is the same height everywhere.
1217    /// - All internal nodes have the minimum number of children.
1218    /// - All leaf nodes are non-empty.
1219    /// - CRLF pairs are never split over chunk boundaries.
1220    #[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    /// Checks that CRLF pairs are never split over chunk boundaries.
1228    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    //-----------------------------------------------------------------------
1244    // Internal utilities
1245
1246    /// Iteratively replaces the root node with its child if it only has
1247    /// one child.
1248    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
1261/// # Non-Panicking
1262///
1263/// The methods in this impl block provide non-panicking versions of
1264/// `Rope`'s panicking methods.  They return either `Option::None` or
1265/// `Result::Err()` when their panicking counterparts would have panicked.
1266impl Rope {
1267    /// Non-panicking version of [`insert()`](Rope::insert).
1268    #[inline]
1269    pub fn try_insert(&mut self, char_idx: usize, text: &str) -> Result<()> {
1270        // Bounds check
1271        if char_idx <= self.len_chars() {
1272            // We have three cases here:
1273            // 1. The insertion text is very large, in which case building a new
1274            //    Rope out of it and splicing it into the existing Rope is most
1275            //    efficient.
1276            // 2. The insertion text is somewhat large, in which case splitting it
1277            //    up into chunks and repeatedly inserting them is the most
1278            //    efficient.  The splitting is necessary because the insertion code
1279            //    only works correctly below a certain insertion size.
1280            // 3. The insertion text is small, in which case we can simply insert
1281            //    it.
1282            //
1283            // Cases #2 and #3 are rolled into one case here, where case #3 just
1284            // results in the text being "split" into only one chunk.
1285            //
1286            // The boundary for what constitutes "very large" text was arrived at
1287            // experimentally, by testing at what point Rope build + splice becomes
1288            // faster than split + repeated insert.  This constant is likely worth
1289            // revisiting from time to time as Ropey evolves.
1290            if text.len() > MAX_BYTES * 6 {
1291                // Case #1: very large text, build rope and splice it in.
1292                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                // Cases #2 and #3: split into chunks and repeatedly insert.
1298                let mut text = text;
1299                while !text.is_empty() {
1300                    // Split a chunk off from the end of the text.
1301                    // We do this from the end instead of the front so that
1302                    // the repeated insertions can keep re-using the same
1303                    // insertion point.
1304                    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                    // Do the insertion.
1313                    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    /// Non-panicking version of [`insert_char()`](Rope::insert_char).
1323    #[inline]
1324    pub fn try_insert_char(&mut self, char_idx: usize, ch: char) -> Result<()> {
1325        // Bounds check
1326        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    /// Non-panicking version of [`remove()`](Rope::remove).
1336    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            // A special case that the rest of the logic doesn't handle
1354            // correctly.
1355            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    /// Non-panicking version of [`split_off()`](Rope::split_off).
1380    pub fn try_split_off(&mut self, char_idx: usize) -> Result<Self> {
1381        // Bounds check
1382        if char_idx <= self.len_chars() {
1383            if char_idx == 0 {
1384                // Special case 1
1385                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                // Special case 2
1390                Ok(Rope::new())
1391            } else {
1392                // Do the split
1393                let mut new_rope = Rope {
1394                    root: Arc::new(Arc::make_mut(&mut self.root).split(char_idx)),
1395                };
1396
1397                // Fix up the edges
1398                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    /// Non-panicking version of [`byte_to_char()`](Rope::byte_to_char).
1411    #[inline]
1412    pub fn try_byte_to_char(&self, byte_idx: usize) -> Result<usize> {
1413        // Bounds check
1414        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    /// Non-panicking version of [`byte_to_line()`](Rope::byte_to_line).
1423    #[inline]
1424    pub fn try_byte_to_line(&self, byte_idx: usize) -> Result<usize> {
1425        // Bounds check
1426        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    /// Non-panicking version of [`char_to_byte()`](Rope::char_to_byte).
1435    #[inline]
1436    pub fn try_char_to_byte(&self, char_idx: usize) -> Result<usize> {
1437        // Bounds check
1438        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    /// Non-panicking version of [`char_to_line()`](Rope::char_to_line).
1447    #[inline]
1448    pub fn try_char_to_line(&self, char_idx: usize) -> Result<usize> {
1449        // Bounds check
1450        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    /// Non-panicking version of [`char_to_utf16_cu()`](Rope::char_to_utf16_cu).
1459    #[inline]
1460    pub fn try_char_to_utf16_cu(&self, char_idx: usize) -> Result<usize> {
1461        // Bounds check
1462        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    /// Non-panicking version of [`utf16_cu_to_char()`](Rope::utf16_cu_to_char).
1475    #[inline]
1476    pub fn try_utf16_cu_to_char(&self, utf16_cu_idx: usize) -> Result<usize> {
1477        // Bounds check
1478        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    /// Non-panicking version of [`line_to_byte()`](Rope::line_to_byte).
1494    #[inline]
1495    pub fn try_line_to_byte(&self, line_idx: usize) -> Result<usize> {
1496        // Bounds check
1497        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    /// Non-panicking version of [`line_to_char()`](Rope::line_to_char).
1510    #[inline]
1511    pub fn try_line_to_char(&self, line_idx: usize) -> Result<usize> {
1512        // Bounds check
1513        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    /// Non-panicking version of [`byte()`](Rope::byte).
1526    #[inline]
1527    pub fn get_byte(&self, byte_idx: usize) -> Option<u8> {
1528        // Bounds check
1529        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    /// Non-panicking version of [`char()`](Rope::char).
1539    #[inline]
1540    pub fn get_char(&self, char_idx: usize) -> Option<char> {
1541        // Bounds check
1542        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    /// Non-panicking version of [`line()`](Rope::line).
1552    #[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        // Bounds check
1560        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    /// Non-panicking version of [`chunk_at_byte()`](Rope::chunk_at_byte).
1583    #[inline]
1584    pub fn get_chunk_at_byte(&self, byte_idx: usize) -> Option<(&str, usize, usize, usize)> {
1585        // Bounds check
1586        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    /// Non-panicking version of [`chunk_at_char()`](Rope::chunk_at_char).
1600    #[inline]
1601    pub fn get_chunk_at_char(&self, char_idx: usize) -> Option<(&str, usize, usize, usize)> {
1602        // Bounds check
1603        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    /// Non-panicking version of [`chunk_at_line_break()`](Rope::chunk_at_line_break).
1617    #[inline]
1618    pub fn get_chunk_at_line_break(
1619        &self,
1620        line_break_idx: usize,
1621    ) -> Option<(&str, usize, usize, usize)> {
1622        // Bounds check
1623        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    /// Non-panicking version of [`slice()`](Rope::slice).
1637    #[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        // Bounds check
1646        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    /// Non-panicking version of [`byte_slice()`](Rope::byte_slice).
1654    #[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        // Bounds checks.
1670        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    /// Non-panicking version of [`bytes_at()`](Rope::bytes_at).
1718    #[inline]
1719    pub fn get_bytes_at(&self, byte_idx: usize) -> Option<Bytes> {
1720        // Bounds check
1721        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    /// Non-panicking version of [`chars_at()`](Rope::chars_at).
1736    #[inline]
1737    pub fn get_chars_at(&self, char_idx: usize) -> Option<Chars> {
1738        // Bounds check
1739        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    /// Non-panicking version of [`lines_at()`](Rope::lines_at).
1754    #[inline]
1755    pub fn get_lines_at(&self, line_idx: usize) -> Option<Lines> {
1756        // Bounds check
1757        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    /// Non-panicking version of [`chunks_at_byte()`](Rope::chunks_at_byte).
1770    #[inline]
1771    pub fn get_chunks_at_byte(&self, byte_idx: usize) -> Option<(Chunks, usize, usize, usize)> {
1772        // Bounds check
1773        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    /// Non-panicking version of [`chunks_at_char()`](Rope::chunks_at_char).
1787    #[inline]
1788    pub fn get_chunks_at_char(&self, char_idx: usize) -> Option<(Chunks, usize, usize, usize)> {
1789        // Bounds check
1790        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    /// Non-panicking version of [`chunks_at_line_break()`](Rope::chunks_at_line_break).
1804    #[inline]
1805    pub fn get_chunks_at_line_break(
1806        &self,
1807        line_break_idx: usize,
1808    ) -> Option<(Chunks, usize, usize, usize)> {
1809        // Bounds check
1810        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
1824//==============================================================
1825// Conversion impls
1826
1827impl<'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
1848/// Will share data where possible.
1849///
1850/// Runs in O(log N) time.
1851impl<'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                // Chop off right end if needed
1865                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                // Chop off left end if needed
1875                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                // Return the rope
1885                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
1915/// Attempts to borrow the contents of the `Rope`, but will convert to an
1916/// owned string if the contents is not contiguous in memory.
1917///
1918/// Runs in best case O(1), worst case O(N).
1919impl<'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
1969//==============================================================
1970// Other impls
1971
1972impl 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//==============================================================
2081
2082#[cfg(test)]
2083mod tests {
2084    use super::*;
2085    use crate::str_utils::*;
2086    use std::hash::{Hash, Hasher};
2087
2088    // 127 bytes, 103 chars, 1 line
2089    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    // 124 bytes, 100 chars, 4 lines
2093    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    // 127 bytes, 107 chars, 111 utf16 code units, 1 line
2097    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        // Make sure CRLF pairs get merged properly, via
2336        // assert_invariants() below.
2337        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        // Make sure removing nothing actually does nothing.
2349        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        // Make sure removing everything works.
2361        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        // Make sure removing a large range works.
2373        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); // Wrong ordering of start/end on purpose.
2386    }
2387
2388    #[test]
2389    #[should_panic]
2390    fn remove_07() {
2391        let mut r = Rope::from_str(TEXT);
2392        r.remove(102..104); // Removing past the end
2393    }
2394
2395    #[test]
2396    #[should_panic]
2397    fn remove_08() {
2398        let mut r = Rope::from_str(TEXT);
2399        r.remove(103..104); // Removing past the end
2400    }
2401
2402    #[test]
2403    #[should_panic]
2404    fn remove_09() {
2405        let mut r = Rope::from_str(TEXT);
2406        r.remove(104..104); // Removing past the end
2407    }
2408
2409    #[test]
2410    #[should_panic]
2411    fn remove_10() {
2412        let mut r = Rope::from_str(TEXT);
2413        r.remove(104..105); // Removing past the end
2414    }
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); // One past the end of the rope
2519    }
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        // UTF-8 for "wide exclamation mark"
2920        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        // First chunk
3102        {
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        // Middle chunks
3111        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        // Last chunk
3121        {
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); // Wrong ordering on purpose.
3172    }
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); // Wrong ordering on purpose.
3223    }
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        // Not a char boundary.
3237        r.byte_slice(..96);
3238    }
3239
3240    #[test]
3241    #[should_panic]
3242    fn byte_slice_08() {
3243        let r = Rope::from_str(TEXT);
3244        // Not a char boundary.
3245        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        // Make sure it's borrowed.
3340        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    // Iterator tests are in the iter module
3455}