Skip to content

Commit

Permalink
SmolStrBuilder::push
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Sep 3, 2024
1 parent db4d3c0 commit d6b84ac
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 5 deletions.
27 changes: 23 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,9 +744,30 @@ impl SmolStrBuilder {
})
}

/// Appends the given [`char`] to the end of `self`'s buffer.
pub fn push(&mut self, c: char) {
match self {
SmolStrBuilder::Inline { len, buf } => {
let char_len = c.len_utf8();
let new_len = *len + char_len;
if new_len <= INLINE_CAP {
c.encode_utf8(&mut buf[*len..]);
*len += char_len;
} else {
let mut heap = String::with_capacity(new_len);
// copy existing inline bytes over to the heap
// SAFETY: inline data is guaranteed to be valid utf8 for `old_len` bytes
unsafe { heap.as_mut_vec().extend_from_slice(buf) };
heap.push(c);
*self = SmolStrBuilder::Heap(heap);
}
}
SmolStrBuilder::Heap(h) => h.push(c),
}
}

/// Appends a given string slice onto the end of `self`'s buffer.
pub fn push_str(&mut self, s: &str) {
// if currently on the stack
match self {
Self::Inline { len, buf } => {
let old_len = *len;
Expand All @@ -762,9 +783,7 @@ impl SmolStrBuilder {

// copy existing inline bytes over to the heap
// SAFETY: inline data is guaranteed to be valid utf8 for `old_len` bytes
unsafe {
heap.as_mut_vec().extend_from_slice(&buf[..old_len]);
}
unsafe { heap.as_mut_vec().extend_from_slice(&buf[..old_len]) };
heap.push_str(s);
*self = SmolStrBuilder::Heap(heap);
}
Expand Down
35 changes: 34 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ fn test_to_smolstr() {
}
}
#[test]
fn test_builder() {
fn test_builder_push_str() {
//empty
let builder = SmolStrBuilder::new();
assert_eq!("", builder.finish());
Expand Down Expand Up @@ -292,6 +292,39 @@ fn test_builder() {
assert_eq!("a".repeat(46), s);
}

#[test]
fn test_builder_push() {
//empty
let builder = SmolStrBuilder::new();
assert_eq!("", builder.finish());

// inline push
let mut builder = SmolStrBuilder::new();
builder.push('a');
builder.push('b');
let s = builder.finish();
assert!(!s.is_heap_allocated());
assert_eq!("ab", s);

// inline max push
let mut builder = SmolStrBuilder::new();
for _ in 0..23 {
builder.push('a');
}
let s = builder.finish();
assert!(!s.is_heap_allocated());
assert_eq!("a".repeat(23), s);

// heap push
let mut builder = SmolStrBuilder::new();
for _ in 0..24 {
builder.push('a');
}
let s = builder.finish();
assert!(s.is_heap_allocated());
assert_eq!("a".repeat(24), s);
}

#[cfg(test)]
mod test_str_ext {
use smol_str::StrExt;
Expand Down

0 comments on commit d6b84ac

Please sign in to comment.