Skip to content

Commit

Permalink
u
Browse files Browse the repository at this point in the history
  • Loading branch information
SyMind committed Dec 28, 2024
1 parent 7674774 commit df823ce
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 32 deletions.
11 changes: 11 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,9 @@ pub trait SourceText<'a>: Default + Clone + ToString {
/// Returns an iterator over the char indices in the text.
fn char_indices(&self) -> impl Iterator<Item = (usize, char)>;

/// Returns an iterator over the [`char`]s of a string slice.
fn chars(&self) -> impl DoubleEndedIterator<Item = char>;

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

Expand Down Expand Up @@ -1293,6 +1296,10 @@ impl<'a> SourceText<'a> for Rope<'a> {
self.char_indices()
}

fn chars(&self) -> impl DoubleEndedIterator<Item = char> {
(*self).chars()
}

fn byte_slice(&self, range: Range<usize>) -> Self {
self.byte_slice(range)
}
Expand Down Expand Up @@ -1335,6 +1342,10 @@ impl<'a> SourceText<'a> for &'a str {
(*self).char_indices()
}

fn chars(&self) -> impl DoubleEndedIterator<Item = char> {
(*self).chars()
}

fn byte_slice(&self, range: Range<usize>) -> Self {
self.get(range).unwrap_or_default()
}
Expand Down
18 changes: 11 additions & 7 deletions src/rope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,16 @@ impl<'a> Rope<'a> {
Repr::Light(s) => RopeChars {
iters: vec![s.chars()],
left: 0,
right: 0
right: 0,
},
Repr::Full(data) => {
let iters = data.iter().map(|(s, _)| s.chars()).collect::<Vec<_>>();
let len = iters.len();
RopeChars { iters, left: 0, right: (len - 1) as u32 }
RopeChars {
iters,
left: 0,
right: (len - 1) as u32,
}
}
}
}
Expand Down Expand Up @@ -959,10 +963,10 @@ fn end_bound_to_range_end(end: Bound<&usize>) -> Option<usize> {
pub struct RopeChars<'a> {
iters: Vec<Chars<'a>>,
left: u32,
right: u32
right: u32,
}

impl<'a> Iterator for RopeChars<'a> {
impl Iterator for RopeChars<'_> {
type Item = char;

#[inline]
Expand All @@ -972,23 +976,23 @@ impl<'a> Iterator for RopeChars<'a> {
return None;
}
if let Some(char) = self.iters[left].next() {
return Some(char);
Some(char)
} else {
self.left += 1;
self.next()
}
}
}

impl<'a> DoubleEndedIterator for RopeChars<'a> {
impl DoubleEndedIterator for RopeChars<'_> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let right = self.right as usize;
if right == 0 {
return self.iters[right].next_back();
}
if let Some(char) = self.iters[right].next_back() {
return Some(char);
Some(char)
} else {
self.right -= 1;
self.next_back()
Expand Down
66 changes: 41 additions & 25 deletions src/with_indices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,42 +36,58 @@ where

let line_len = self.line.len();

let mut start_byte_index = None;
let mut end_byte_index = None;
let mut start_byte_index =
if start_char_index == 0 { Some(0) } else { None };
let mut end_byte_index = if end_char_index == usize::MAX {
Some(line_len)
} else {
None
};

let (last_char_index, last_byte_index) =
*self.last_char_index_to_byte_index.borrow();
let mut last_byte_index = last_byte_index as usize;
let mut byte_index = last_byte_index as usize;
let mut char_index = last_char_index as usize;
if start_char_index < last_char_index as usize {
char_index = 0;
last_byte_index = 0;
}
for (byte_index, _) in self
.line
.byte_slice(last_byte_index..line_len)
.char_indices()

if start_char_index >= last_char_index as usize
|| end_char_index >= last_char_index as usize
{
if char_index == start_char_index {
start_byte_index = Some(byte_index + last_byte_index);
if end_char_index == usize::MAX {
for char in self.line.byte_slice(byte_index..line_len).chars() {
if end_byte_index.is_some() {
break;
}
if char_index == start_char_index {
start_byte_index = Some(byte_index);
*self.last_char_index_to_byte_index.borrow_mut() =
(char_index as u32, byte_index as u32);
}
if char_index == end_char_index {
end_byte_index = Some(byte_index);
*self.last_char_index_to_byte_index.borrow_mut() =
(char_index as u32, byte_index as u32);
}
byte_index += char.len_utf8();
char_index += 1;
}
if char_index == end_char_index {
end_byte_index = Some(byte_index + last_byte_index);
*self.last_char_index_to_byte_index.borrow_mut() =
(end_char_index as u32, (byte_index + last_byte_index) as u32);
break;
} else {
for char in self.line.byte_slice(0..byte_index).chars().rev() {
if start_byte_index.is_some() {
break;
}
if char_index == end_char_index {
end_byte_index = Some(byte_index);
*self.last_char_index_to_byte_index.borrow_mut() =
(char_index as u32, byte_index as u32);
}
if char_index == start_char_index {
start_byte_index = Some(byte_index);
}
byte_index -= char.len_utf8();
char_index -= 1;
}
char_index += 1;
}

let start_byte_index = if let Some(start_byte_index) = start_byte_index {
start_byte_index
} else {
return S::default();
};
let start_byte_index = start_byte_index.unwrap_or(line_len);
let end_byte_index = end_byte_index.unwrap_or(line_len);

#[allow(unsafe_code)]
Expand Down

0 comments on commit df823ce

Please sign in to comment.