Struct ropey::Rope

source · []
pub struct Rope { /* private fields */ }
Expand description

A utf8 text rope.

The time complexity of nearly all edit and query operations on Rope are worst-case O(log N) in the length of the rope. Rope is designed to work efficiently even for huge (in the gigabytes) and pathological (all on one line) texts.

Editing Operations

The primary editing operations on Rope are insertion and removal of text. For example:

let mut rope = Rope::from_str("Hello みんなさん!");
rope.remove(6..11);
rope.insert(6, "world");

assert_eq!(rope, "Hello world!");

Query Operations

Rope provides a rich set of efficient query functions, including querying rope length in bytes/chars/lines, fetching individual chars or lines, and converting between byte/char/line indices. For example, to find the starting char index of a given line:

let rope = Rope::from_str("Hello みんなさん!\nHow are you?\nThis text has multiple lines!");

assert_eq!(rope.line_to_char(0), 0);
assert_eq!(rope.line_to_char(1), 13);
assert_eq!(rope.line_to_char(2), 26);

Slicing

You can take immutable slices of a Rope using slice():

let mut rope = Rope::from_str("Hello みんなさん!");
let middle = rope.slice(3..8);

assert_eq!(middle, "lo みん");

Cloning

Cloning Ropes is extremely cheap, running in O(1) time and taking a small constant amount of memory for the new clone, regardless of text size. This is accomplished by data sharing between Rope clones. The memory used by clones only grows incrementally as the their contents diverge due to edits. All of this is thread safe, so clones can be sent freely between threads.

The primary intended use-case for this feature is to allow asynchronous processing of Ropes. For example, saving a large document to disk in a separate thread while the user continues to perform edits.

Implementations

Creates an empty Rope.

Creates a Rope from a string slice.

Runs in O(N) time.

Creates a Rope from the output of a reader.

This is a convenience function, and provides no specific guarantees about performance or internal implementation aside from the runtime complexity listed below.

When more precise control over IO behavior, buffering, etc. is desired, you should handle IO yourself and use RopeBuilder to build the Rope.

Runs in O(N) time.

Errors
  • If the reader returns an error, from_reader stops and returns that error.
  • If non-utf8 data is encountered, an IO error with kind InvalidData is returned.

Note: some data from the reader is likely consumed even if there is an error.

Writes the contents of the Rope to a writer.

This is a convenience function, and provides no specific guarantees about performance or internal implementation aside from the runtime complexity listed below.

When more precise control over IO behavior, buffering, etc. is desired, you should handle IO yourself and use the Chunks iterator to iterate through the Rope’s contents.

Runs in O(N) time.

Errors
  • If the writer returns an error, write_to stops and returns that error.

Note: some data may have been written even if an error is returned.

Total number of bytes in the Rope.

Runs in O(1) time.

Total number of chars in the Rope.

Runs in O(1) time.

Total number of lines in the Rope.

Runs in O(1) time.

Total number of utf16 code units that would be in Rope if it were encoded as utf16.

Ropey stores text internally as utf8, but sometimes it is necessary to interact with external APIs that still use utf16. This function is primarily intended for such situations, and is otherwise not very useful.

Runs in O(1) time.

Total size of the Rope’s text buffer space, in bytes.

This includes unoccupied text buffer space. You can calculate the unoccupied space with capacity() - len_bytes(). In general, there will always be some unoccupied buffer space.

Runs in O(N) time.

Shrinks the Rope’s capacity to the minimum possible.

This will rarely result in capacity() == len_bytes(). Rope stores text in a sequence of fixed-capacity chunks, so an exact fit only happens for texts that are both a precise multiple of that capacity and have code point boundaries that line up exactly with the capacity boundaries.

After calling this, the difference between capacity() and len_bytes() is typically under 1KB per megabyte of text in the Rope.

NOTE: calling this on a Rope clone causes it to stop sharing all data with its other clones. In such cases you will very likely be increasing total memory usage despite shrinking the Rope’s capacity.

Runs in O(N) time, and uses O(log N) additional space during shrinking.

Inserts text at char index char_idx.

Runs in O(M + log N) time, where N is the length of the Rope and M is the length of text.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Inserts a single char ch at char index char_idx.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Removes the text in the given char index range.

Uses range syntax, e.g. 2..7, 2.., etc. The range is in char indices.

Runs in O(M + log N) time, where N is the length of the Rope and M is the length of the range being removed.

Example
let mut rope = Rope::from_str("Hello world!");
rope.remove(5..);

assert_eq!("Hello", rope);
Panics

Panics if the start of the range is greater than the end, or if the end is out of bounds (i.e. end > len_chars()).

Splits the Rope at char_idx, returning the right part of the split.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Appends a Rope to the end of this one, consuming the other Rope.

Runs in O(log N) time.

Returns the char index of the given byte.

Notes:

  • If the byte is in the middle of a multi-byte char, returns the index of the char that the byte belongs to.
  • byte_idx can be one-past-the-end, which will return one-past-the-end char index.

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx > len_bytes()).

Returns the line index of the given byte.

Notes:

  • Lines are zero-indexed. This is functionally equivalent to counting the line endings before the specified byte.
  • byte_idx can be one-past-the-end, which will return the last line index.

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx > len_bytes()).

Returns the byte index of the given char.

Notes:

  • char_idx can be one-past-the-end, which will return one-past-the-end byte index.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Returns the line index of the given char.

Notes:

  • Lines are zero-indexed. This is functionally equivalent to counting the line endings before the specified char.
  • char_idx can be one-past-the-end, which will return the last line index.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Returns the utf16 code unit index of the given char.

Ropey stores text internally as utf8, but sometimes it is necessary to interact with external APIs that still use utf16. This function is primarily intended for such situations, and is otherwise not very useful.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Returns the char index of the given utf16 code unit.

Ropey stores text internally as utf8, but sometimes it is necessary to interact with external APIs that still use utf16. This function is primarily intended for such situations, and is otherwise not very useful.

Note: if the utf16 code unit is in the middle of a char, returns the index of the char that it belongs to.

Runs in O(log N) time.

Panics

Panics if utf16_cu_idx is out of bounds (i.e. utf16_cu_idx > len_utf16_cu()).

Returns the byte index of the start of the given line.

Notes:

  • Lines are zero-indexed.
  • line_idx can be one-past-the-end, which will return one-past-the-end byte index.

Runs in O(log N) time.

Panics

Panics if line_idx is out of bounds (i.e. line_idx > len_lines()).

Returns the char index of the start of the given line.

Notes:

  • Lines are zero-indexed.
  • line_idx can be one-past-the-end, which will return one-past-the-end char index.

Runs in O(log N) time.

Panics

Panics if line_idx is out of bounds (i.e. line_idx > len_lines()).

Returns the byte at byte_idx.

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx >= len_bytes()).

Returns the char at char_idx.

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx >= len_chars()).

Returns the line at line_idx.

Note: lines are zero-indexed.

Runs in O(log N) time.

Panics

Panics if line_idx is out of bounds (i.e. line_idx >= len_lines()).

Returns the chunk containing the given byte index.

Also returns the byte and char indices of the beginning of the chunk and the index of the line that the chunk starts on.

Note: for convenience, a one-past-the-end byte_idx returns the last chunk of the RopeSlice.

The return value is organized as (chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx > len_bytes()).

Returns the chunk containing the given char index.

Also returns the byte and char indices of the beginning of the chunk and the index of the line that the chunk starts on.

Note: for convenience, a one-past-the-end char_idx returns the last chunk of the RopeSlice.

The return value is organized as (chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Returns the chunk containing the given line break.

Also returns the byte and char indices of the beginning of the chunk and the index of the line that the chunk starts on.

Note: for convenience, both the beginning and end of the rope are considered line breaks for the purposes of indexing. For example, in the string "Hello \n world!" 0 would give the first chunk, 1 would give the chunk containing the newline character, and 2 would give the last chunk.

The return value is organized as (chunk, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if line_break_idx is out of bounds (i.e. line_break_idx > len_lines()).

Gets an immutable slice of the Rope, using char indices.

Uses range syntax, e.g. 2..7, 2.., etc.

Example
let rope = Rope::from_str("Hello world!");
let slice = rope.slice(..5);

assert_eq!("Hello", slice);

Runs in O(log N) time.

Panics

Panics if the start of the range is greater than the end, or if the end is out of bounds (i.e. end > len_chars()).

Gets and immutable slice of the Rope, using byte indices.

Uses range syntax, e.g. 2..7, 2.., etc.

Runs in O(log N) time.

Panics

Panics if:

  • The start of the range is greater than the end.
  • The end is out of bounds (i.e. end > len_bytes()).
  • The range doesn’t align with char boundaries.

Creates an iterator over the bytes of the Rope.

Runs in O(log N) time.

Creates an iterator over the bytes of the Rope, starting at byte byte_idx.

If byte_idx == len_bytes() then an iterator at the end of the Rope is created (i.e. next() will return None).

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx > len_bytes()).

Creates an iterator over the chars of the Rope.

Runs in O(log N) time.

Creates an iterator over the chars of the Rope, starting at char char_idx.

If char_idx == len_chars() then an iterator at the end of the Rope is created (i.e. next() will return None).

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Creates an iterator over the lines of the Rope.

Runs in O(log N) time.

Creates an iterator over the lines of the Rope, starting at line line_idx.

If line_idx == len_lines() then an iterator at the end of the Rope is created (i.e. next() will return None).

Runs in O(log N) time.

Panics

Panics if line_idx is out of bounds (i.e. line_idx > len_lines()).

Creates an iterator over the chunks of the Rope.

Runs in O(log N) time.

Creates an iterator over the chunks of the Rope, with the iterator starting at the chunk containing byte_idx.

Also returns the byte and char indices of the beginning of the first chunk to be yielded, and the index of the line that chunk starts on.

If byte_idx == len_bytes() an iterator at the end of the Rope (yielding None on a call to next()) is created.

The return value is organized as (iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if byte_idx is out of bounds (i.e. byte_idx > len_bytes()).

Creates an iterator over the chunks of the Rope, with the iterator starting at the chunk containing char_idx.

Also returns the byte and char indices of the beginning of the first chunk to be yielded, and the index of the line that chunk starts on.

If char_idx == len_chars() an iterator at the end of the Rope (yielding None on a call to next()) is created.

The return value is organized as (iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if char_idx is out of bounds (i.e. char_idx > len_chars()).

Creates an iterator over the chunks of the Rope, with the iterator starting at the chunk containing line_break_idx.

Also returns the byte and char indices of the beginning of the first chunk to be yielded, and the index of the line that chunk starts on.

Note: for convenience, both the beginning and end of the Rope are considered line breaks for the purposes of indexing. For example, in the string "Hello \n world!" 0 would create an iterator starting on the first chunk, 1 would create an iterator starting on the chunk containing the newline character, and 2 would create an iterator at the end of the Rope (yielding None on a call to next()).

The return value is organized as (iterator, chunk_byte_idx, chunk_char_idx, chunk_line_idx).

Runs in O(log N) time.

Panics

Panics if line_break_idx is out of bounds (i.e. line_break_idx > len_lines()).

Non-Panicking

The methods in this impl block provide non-panicking versions of Rope’s panicking methods. They return either Option::None or Result::Err() when their panicking counterparts would have panicked.

Non-panicking version of insert().

Non-panicking version of insert_char().

Non-panicking version of remove().

Non-panicking version of split_off().

Non-panicking version of byte_to_char().

Non-panicking version of byte_to_line().

Non-panicking version of char_to_byte().

Non-panicking version of char_to_line().

Non-panicking version of char_to_utf16_cu().

Non-panicking version of utf16_cu_to_char().

Non-panicking version of line_to_byte().

Non-panicking version of line_to_char().

Non-panicking version of byte().

Non-panicking version of char().

Non-panicking version of line().

Non-panicking version of chunk_at_byte().

Non-panicking version of chunk_at_char().

Non-panicking version of chunk_at_line_break().

Non-panicking version of slice().

Non-panicking version of byte_slice().

Non-panicking version of bytes_at().

Non-panicking version of chars_at().

Non-panicking version of lines_at().

Non-panicking version of chunks_at_byte().

Non-panicking version of chunks_at_char().

Non-panicking version of chunks_at_line_break().

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Formats the value using the given formatter. Read more

Converts to this type from the input type.

Attempts to borrow the contents of the Rope, but will convert to an owned string if the contents is not contiguous in memory.

Runs in best case O(1), worst case O(N).

Converts to this type from the input type.

Converts to this type from the input type.

Converts to this type from the input type.

Converts to this type from the input type.

Converts to this type from the input type.

Will share data where possible.

Runs in O(log N) time.

Converts to this type from the input type.

Converts to this type from the input type.

Creates a value from an iterator. Read more

Creates a value from an iterator. Read more

Creates a value from an iterator. Read more

Feeds this value into the given Hasher. Read more

Feeds a slice of this type into the given Hasher. Read more

This method returns an Ordering between self and other. Read more

Compares and returns the maximum of two values. Read more

Compares and returns the minimum of two values. Read more

Restrict a value to a certain interval. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

Converts the given value to a String. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.