Skip to content

Commit

Permalink
(#1) add char_count api because that information comes free
Browse files Browse the repository at this point in the history
  • Loading branch information
ultrabear committed Nov 8, 2023
1 parent ab510e0 commit 3247ea8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/borrowed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ impl<'a> IndexedChars<'a> {
self.inner.get_char(self.buf, index)
}

/// Returns the number of chars present in the backing string, this operation is free thanks to
/// how [`IndexedChars`] is constructed
#[must_use]
pub fn char_count(&self) -> usize {
self.inner.char_count(self.buf)
}

/// Returns a reference to the backing `&str`
#[must_use]
pub fn as_str(&self) -> &str {
Expand Down
11 changes: 11 additions & 0 deletions src/indexed_chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl IndexedCharsInner {
pub(crate) fn new(s: &str) -> Self {
// this is expensive but it lets us avoid big reallocs
// it also lets us niche on ascii strings
// maybe-TODO(ultrabear) replace with no-std bytecount::num_chars?
let charlen = s.chars().count();

// if the number of chars is equal to the number of bytes we can skip allocating at all
Expand Down Expand Up @@ -63,6 +64,16 @@ impl IndexedCharsInner {
self.chars.is_empty()
}

/// Computes the amount of chars in the given string in O(1) time,
/// the string passed must be the one this index was created with.
pub(crate) fn char_count(&self, buf: &str) -> usize {
if self.is_ascii() {
buf.len()
} else {
self.chars.len()
}
}

/// Gets a char from a string using the index, the string passed must be the one this index was created with
pub(crate) fn get_char(&self, buf: &str, index: usize) -> Option<char> {
// niche on empty chars (ascii optimization)
Expand Down
7 changes: 7 additions & 0 deletions src/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ impl OwnedIndexedChars {
self.inner.get_char(&self.buf, index)
}

/// Returns the number of chars present in the backing string, this operation is free thanks to
/// how [`OwnedIndexedChars`] is constructed
#[must_use]
pub fn char_count(&self) -> usize {
self.inner.char_count(&self.buf)
}

/// Drops index data and returns backing `String` allocation.
#[must_use]
pub fn into_string(self) -> String {
Expand Down

0 comments on commit 3247ea8

Please sign in to comment.