pub struct ExString<'a> { /* private fields */ }Expand description
A growable, allocator-backed UTF-8 string.
§Invariant
The byte buffer buf always contains valid UTF-8. Methods that accept
raw &str or char values uphold this invariant automatically. The
as_str / as_bytes accessors expose the buffer read-only so callers
cannot introduce invalid UTF-8.
§Lifetime
The allocator reference 'a must outlive the ExString.
Implementations§
Source§impl<'a> ExString<'a>
impl<'a> ExString<'a>
Sourcepub fn new(alloc: &'a dyn Allocator) -> Self
pub fn new(alloc: &'a dyn Allocator) -> Self
Creates a new, empty ExString that will allocate through alloc.
Examples found in repository?
More examples
9fn main() {
10 let sys = CountingAllocator::new(SystemAllocator);
11
12 println!("=== ExBox & SystemAllocator ===");
13 {
14 let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15 println!("Box value: {}", *b);
16 }
17
18 let stats = sys.stats();
19 println!("Allocated: {} bytes", stats.bytes_allocated);
20 println!("Deallocated: {} bytes", stats.bytes_freed);
21 println!("Live bytes: {}\n", stats.bytes_live);
22
23 println!("=== ExVec & Arena (Linear Allocation) ===");
24 {
25 let arena = ArenaAllocator::new(&sys);
26
27 let mut v = ExVec::new(&arena);
28 for i in 0..5 {
29 v.push(i * 10);
30 }
31 println!("Vec: {:?}", v.as_slice());
32
33 arena.reset();
34 println!("Arena reset performed");
35 }
36
37 println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38 {
39 let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40 .expect("Failed to create Pool");
41
42 let mut s = ExString::new(&pool);
43 s.push_str("Hello from ZigZag!");
44
45 println!("String in Pool: {}", s.as_str());
46 println!("Pool free slots: {}", pool.free_count());
47 }
48
49 println!("\n=== Final Global Stats ===");
50 let final_stats = sys.stats();
51 println!("Total count of alloc() calls: {}", final_stats.allocs);
52 println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53 println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54 println!("Total bytes freed: {}", final_stats.bytes_freed);
55 println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}Sourcepub fn from_str(s: &str, alloc: &'a dyn Allocator) -> Self
pub fn from_str(s: &str, alloc: &'a dyn Allocator) -> Self
Creates an ExString pre-populated with a copy of s.
Sourcepub fn push_str(&mut self, s: &str)
pub fn push_str(&mut self, s: &str)
Appends the string slice s to the end of this string.
Grows the underlying buffer if necessary.
§Panics
Panics if the backing allocator cannot satisfy the growth request.
Examples found in repository?
9fn main() {
10 let sys = CountingAllocator::new(SystemAllocator);
11
12 println!("=== ExBox & SystemAllocator ===");
13 {
14 let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15 println!("Box value: {}", *b);
16 }
17
18 let stats = sys.stats();
19 println!("Allocated: {} bytes", stats.bytes_allocated);
20 println!("Deallocated: {} bytes", stats.bytes_freed);
21 println!("Live bytes: {}\n", stats.bytes_live);
22
23 println!("=== ExVec & Arena (Linear Allocation) ===");
24 {
25 let arena = ArenaAllocator::new(&sys);
26
27 let mut v = ExVec::new(&arena);
28 for i in 0..5 {
29 v.push(i * 10);
30 }
31 println!("Vec: {:?}", v.as_slice());
32
33 arena.reset();
34 println!("Arena reset performed");
35 }
36
37 println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38 {
39 let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40 .expect("Failed to create Pool");
41
42 let mut s = ExString::new(&pool);
43 s.push_str("Hello from ZigZag!");
44
45 println!("String in Pool: {}", s.as_str());
46 println!("Pool free slots: {}", pool.free_count());
47 }
48
49 println!("\n=== Final Global Stats ===");
50 let final_stats = sys.stats();
51 println!("Total count of alloc() calls: {}", final_stats.allocs);
52 println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53 println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54 println!("Total bytes freed: {}", final_stats.bytes_freed);
55 println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}Sourcepub fn push(&mut self, ch: char)
pub fn push(&mut self, ch: char)
Appends the Unicode scalar ch (encoded as UTF-8) to this string.
§Panics
Panics if the backing allocator cannot satisfy the growth request.
Sourcepub fn as_str(&self) -> &str
pub fn as_str(&self) -> &str
Returns the string content as a &str.
§Safety Justification
The buffer is always valid UTF-8 because only push_str and push
can append bytes, and both sources (&str / char) are guaranteed
to be valid UTF-8 by Rust’s type system. clear simply sets len = 0
without writing invalid bytes.
Examples found in repository?
More examples
9fn main() {
10 let sys = CountingAllocator::new(SystemAllocator);
11
12 println!("=== ExBox & SystemAllocator ===");
13 {
14 let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15 println!("Box value: {}", *b);
16 }
17
18 let stats = sys.stats();
19 println!("Allocated: {} bytes", stats.bytes_allocated);
20 println!("Deallocated: {} bytes", stats.bytes_freed);
21 println!("Live bytes: {}\n", stats.bytes_live);
22
23 println!("=== ExVec & Arena (Linear Allocation) ===");
24 {
25 let arena = ArenaAllocator::new(&sys);
26
27 let mut v = ExVec::new(&arena);
28 for i in 0..5 {
29 v.push(i * 10);
30 }
31 println!("Vec: {:?}", v.as_slice());
32
33 arena.reset();
34 println!("Arena reset performed");
35 }
36
37 println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38 {
39 let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40 .expect("Failed to create Pool");
41
42 let mut s = ExString::new(&pool);
43 s.push_str("Hello from ZigZag!");
44
45 println!("String in Pool: {}", s.as_str());
46 println!("Pool free slots: {}", pool.free_count());
47 }
48
49 println!("\n=== Final Global Stats ===");
50 let final_stats = sys.stats();
51 println!("Total count of alloc() calls: {}", final_stats.allocs);
52 println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53 println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54 println!("Total bytes freed: {}", final_stats.bytes_freed);
55 println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of bytes (not Unicode code points) in the string.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the number of bytes the buffer can hold without reallocating.
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears the string, setting its length to zero.
Does not release the backing allocation.
Sourcepub fn find_byte(&self, byte: u8) -> Option<usize>
pub fn find_byte(&self, byte: u8) -> Option<usize>
Returns the byte offset of the first occurrence of byte, or None.
Sourcepub fn contains_byte(&self, byte: u8) -> bool
pub fn contains_byte(&self, byte: u8) -> bool
Returns true if the string contains the given byte.
Sourcepub fn count_byte(&self, byte: u8) -> usize
pub fn count_byte(&self, byte: u8) -> usize
Returns the number of times byte appears in the string.
Sourcepub fn for_each_byte_match<F: FnMut(usize)>(&self, byte: u8, f: F)
pub fn for_each_byte_match<F: FnMut(usize)>(&self, byte: u8, f: F)
Calls f with the byte offset of every occurrence of byte.
Sourcepub fn replace_byte(&mut self, from: u8, to: u8)
pub fn replace_byte(&mut self, from: u8, to: u8)
Replaces every occurrence of from with to in-place.
§Panics
If from and to have different UTF-8 lengths, the resulting string
may no longer be valid UTF-8. This method is designed for single-byte
replacements only (e.g. replacing b'\n' with b' ').