Struct TextBuffer

Source
pub struct TextBuffer { /* private fields */ }
Expand description

Mutable text storage with a paragraph index (logical line = \n-separated).

Text is stored in a [Rope], while paragraph metadata is rebuilt after each edit. Public offsets are UTF-8 bytes, not character or grapheme indices. Cloning copies the current rope handle and metadata as independent mutable values.

§Examples

use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("first\nsecond");
assert_eq!(buffer.len_bytes(), 12);
assert_eq!(buffer.paragraphs().len(), 2);

Implementations§

Source§

impl TextBuffer

Source

pub fn new() -> Self

Creates an empty buffer at revision zero.

The paragraph index contains one empty 0..0 entry so methods such as Self::paragraph_at always have a paragraph to return.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::new();
assert_eq!(buffer.revision(), 0);
assert_eq!(buffer.paragraphs()[0].byte_range, 0..0);
Source

pub fn from_string(s: impl Into<String>) -> Self

Creates a revision-zero buffer from owned or borrowed UTF-8 text.

Newline bytes terminate and belong to their preceding paragraph. A trailing newline does not create an additional empty paragraph.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("a\nb\n");
assert_eq!(buffer.paragraphs().len(), 2);
assert_eq!(buffer.paragraph_text(0).as_deref(), Some("a\n"));
Source

pub fn revision(&self) -> u64

Returns the global wrapping edit counter.

Every call to Self::edit increments the counter, including edits that leave text unchanged. It starts at zero and wraps from u64::MAX to zero.

§Examples
use ailloli_ui_text::TextBuffer;
let mut buffer = TextBuffer::new();
buffer.edit(0..0, "");
assert_eq!(buffer.revision(), 1);
Source

pub fn len_bytes(&self) -> usize

Returns the current UTF-8 byte length.

This differs from Unicode scalar and grapheme counts for non-ASCII text.

§Examples
use ailloli_ui_text::TextBuffer;
assert_eq!(TextBuffer::from_string("é").len_bytes(), 2);
Source

pub fn as_str(&self) -> String

Copies the entire rope into a contiguous String.

Despite the method name, the result is owned because a Rope is not necessarily contiguous. This operation is O(N) in the text length.

§Examples
use ailloli_ui_text::TextBuffer;
let text: String = TextBuffer::from_string("hello").as_str();
assert_eq!(text, "hello");
Source

pub fn paragraphs(&self) -> &[ParagraphMeta]

Borrows current paragraph metadata in document order.

The slice is never empty for buffers built through public constructors. It is invalidated by the next mutable edit.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("a\nb");
assert_eq!(buffer.paragraphs()[0].byte_range, 0..2);
assert_eq!(buffer.paragraphs()[1].byte_range, 2..3);
Source

pub fn paragraph_text(&self, idx: usize) -> Option<String>

Copies one indexed paragraph into a String.

The returned text includes its terminating newline when present. None means idx is outside Self::paragraphs.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("a\nb");
assert_eq!(buffer.paragraph_text(0).as_deref(), Some("a\n"));
assert_eq!(buffer.paragraph_text(2), None);
Source

pub fn revision_of_paragraph(&self, idx: usize) -> Option<u64>

Returns one paragraph’s revision, or None for an invalid index.

Paragraph revisions initially equal zero. After an edit they identify index entries considered touched or whose byte range changed; they are not guaranteed to advance for a global no-op.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("a\nb");
assert_eq!(buffer.revision_of_paragraph(0), Some(0));
assert_eq!(buffer.revision_of_paragraph(9), None);
Source

pub fn paragraph_at(&self, b: usize) -> usize

Index of the paragraph containing byte b (clamped to the last paragraph).

Newline bytes belong to the paragraph they terminate. An index at or beyond len_bytes() maps to the last paragraph. An empty buffer returns zero for every input.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("a\nb");
assert_eq!(buffer.paragraph_at(1), 0); // newline
assert_eq!(buffer.paragraph_at(2), 1);
assert_eq!(buffer.paragraph_at(usize::MAX), 1);
Source

pub fn edit(&mut self, range: Range<usize>, new_text: &str)

Replaces range (UTF-8 bytes) with new_text. Bumps global and touched paragraph revisions.

Each endpoint is first clamped to len_bytes(). If the range is reversed, its start is lowered to the clamped end, producing an insertion rather than swapping endpoints. Ropey maps an endpoint inside a multibyte scalar to that scalar’s character index; callers should therefore pass valid UTF-8 boundaries when exact replacement is required. The global revision wraps on overflow and advances even for a no-op.

Paragraph metadata is rebuilt in O(N) text time. Entries intersecting the old nonempty range or whose same-index byte range changed receive the new revision; index shifts can consequently invalidate later paragraphs.

§Examples
use ailloli_ui_text::TextBuffer;
let mut buffer = TextBuffer::from_string("abc");
buffer.edit(1..2, "X");
assert_eq!(buffer.as_str(), "aXc");
assert_eq!(buffer.revision(), 1);
Source

pub fn paragraphs_in_byte_range(&self, byte_range: Range<usize>) -> Vec<usize>

Returns paragraph indices whose half-open byte ranges intersect byte_range.

The input is not clamped or reordered. Empty or reversed ranges return an empty vector. Because a newline belongs to its preceding paragraph, a range containing only that newline intersects that preceding paragraph.

§Examples
use ailloli_ui_text::TextBuffer;
let buffer = TextBuffer::from_string("aa\nbb\ncc");
assert_eq!(buffer.paragraphs_in_byte_range(2..6), [0, 1]);
assert!(buffer.paragraphs_in_byte_range(3..3).is_empty());

Trait Implementations§

Source§

impl Clone for TextBuffer

Source§

fn clone(&self) -> TextBuffer

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TextBuffer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TextBuffer

Source§

fn default() -> Self

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

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> ErasedDestructor for T
where T: 'static,