Skip to content

Commit

Permalink
docs: more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
h-a-n-a committed Dec 11, 2024
1 parent 885c2ca commit d300412
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
37 changes: 27 additions & 10 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,17 +1292,34 @@ pub fn stream_and_get_source_and_map<'a, S: StreamChunks>(
(generated_info, map)
}

/// Represents a text source that can be manipulated for source mapping purposes.
pub trait SourceText<'a>: Default + Clone + ToString {
fn split_into_lines(&self) -> impl Iterator<Item = Self>;
fn len(&self) -> usize;
fn ends_with(&self, value: &str) -> bool;
fn char_indices(&self) -> impl Iterator<Item = (usize, char)>;
fn byte_slice(&self, range: Range<usize>) -> Self;
fn is_empty(&self) -> bool;
fn into_rope(self) -> Rope<'a>
where
Self: Sized;
fn get_byte(&self, byte_index: usize) -> Option<u8>;
/// Splits the text into lines, returning an iterator over each line.
/// Each line includes its line ending character if present.
fn split_into_lines(&self) -> impl Iterator<Item = Self>;

/// Returns the length of the text in bytes.
fn len(&self) -> usize;

/// Checks if the text ends with the given string.
fn ends_with(&self, value: &str) -> bool;

/// Returns an iterator over the char indices in the text.
fn char_indices(&self) -> impl Iterator<Item = (usize, char)>;

/// Gets the byte at the specified index, if it exists.
fn get_byte(&self, byte_index: usize) -> Option<u8>;

/// Returns a slice of the text specified by the byte range.
fn byte_slice(&self, range: Range<usize>) -> Self;

/// Returns true if the text is empty.
fn is_empty(&self) -> bool;

/// Converts this text into a Rope.
fn into_rope(self) -> Rope<'a>
where
Self: Sized;
}

impl<'a> SourceText<'a> for Rope<'a> {
Expand Down
27 changes: 20 additions & 7 deletions src/rope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl<'a> Rope<'a> {
Repr::Simple(s) => s
.get(start_range..end_range)
.map(Rope::from)
.ok_or_else(|| Error::Rope("invalid char boundary")),
.ok_or(Error::Rope("invalid char boundary")),
Repr::Complex(data) => {
// [start_chunk
let start_chunk_index = data
Expand All @@ -275,13 +275,15 @@ impl<'a> Rope<'a> {

// same chunk
if start_chunk_index == end_chunk_index {
let (chunk, start_pos) = data[start_chunk_index];
// SAFETY: start_chunk_index guarantees valid range
let (chunk, start_pos) =
unsafe { data.get_unchecked(start_chunk_index) };
let start = start_range - start_pos;
let end = end_range - start_pos;
return chunk
.get(start..end)
.map(Rope::from)
.ok_or_else(|| Error::Rope("invalid char boundary"));
.ok_or(Error::Rope("invalid char boundary"));
}

if end_chunk_index < start_chunk_index {
Expand All @@ -295,7 +297,8 @@ impl<'a> Rope<'a> {
// different chunk
// [start_chunk, end_chunk]
(start_chunk_index..end_chunk_index + 1).try_for_each(|i| {
let (chunk, start_pos) = data[i];
// SAFETY: [start_chunk_index, end_chunk_index] guarantees valid range
let (chunk, start_pos) = unsafe { data.get_unchecked(i) };

if start_chunk_index == i {
let start = start_range - start_pos;
Expand Down Expand Up @@ -328,8 +331,15 @@ impl<'a> Rope<'a> {
}
}

/// Unchecked version of [Rope::byte_slice].
/// Invariant: The range must be valid and on char boundaries.
/// Range-unchecked version of [Rope::byte_slice].
///
/// # Safety
///
/// This is not safe, due to the following invariants that must be upheld:
///
/// - Range must be within bounds.
/// - Range start must be less than or equal to the end.
/// - Both range start and end must be on char boundaries.
pub unsafe fn byte_slice_unchecked<R>(&self, range: R) -> Rope<'a>
where
R: RangeBounds<usize>,
Expand Down Expand Up @@ -425,7 +435,7 @@ impl<'a> Rope<'a> {
}
}

/// Returns the underlying str if this is a simple rope.
/// Returns the underlying &str if this is a simple rope.
pub fn get_simple(&self) -> Option<&'a str> {
match &self.repr {
Repr::Simple(s) => Some(s),
Expand Down Expand Up @@ -503,6 +513,9 @@ impl Default for Rope<'_> {
}
}

// Implement `ToString` than `Display` to manually allocate the string with capacity.
// This is faster than using `Display` and `write!` for large ropes.
#[allow(clippy::to_string_trait_impl)]
impl ToString for Rope<'_> {
fn to_string(&self) -> String {
match &self.repr {
Expand Down
1 change: 1 addition & 0 deletions tests/compat_source.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(missing_docs)]
use std::borrow::Cow;
use std::hash::Hash;

Expand Down

0 comments on commit d300412

Please sign in to comment.