Skip to main content

ExString

Struct ExString 

Source
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>

Source

pub fn new(alloc: &'a dyn Allocator) -> Self

Creates a new, empty ExString that will allocate through alloc.

Examples found in repository?
examples/pool_string.rs (line 11)
6fn main() {
7    let sys = SystemAllocator;
8
9    let pool = PoolAllocator::typed::<[u8; 128]>(&sys, 5).unwrap();
10
11    let mut log = ExString::new(&pool);
12    write!(log, "Status: {}, Code: {}", "OK", 200).unwrap();
13
14    println!("Log message: {}", log.as_str());
15    println!("Slots left in pool: {}", pool.free_count());
16}
More examples
Hide additional examples
examples/full.rs (line 42)
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}
Source

pub fn from_str(s: &str, alloc: &'a dyn Allocator) -> Self

Creates an ExString pre-populated with a copy of s.

Source

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?
examples/full.rs (line 43)
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}
Source

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.

Source

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?
examples/pool_string.rs (line 14)
6fn main() {
7    let sys = SystemAllocator;
8
9    let pool = PoolAllocator::typed::<[u8; 128]>(&sys, 5).unwrap();
10
11    let mut log = ExString::new(&pool);
12    write!(log, "Status: {}, Code: {}", "OK", 200).unwrap();
13
14    println!("Log message: {}", log.as_str());
15    println!("Slots left in pool: {}", pool.free_count());
16}
More examples
Hide additional examples
examples/full.rs (line 45)
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}
Source

pub fn len(&self) -> usize

Returns the number of bytes (not Unicode code points) in the string.

Source

pub fn is_empty(&self) -> bool

Returns true if the string contains no bytes.

Source

pub fn capacity(&self) -> usize

Returns the number of bytes the buffer can hold without reallocating.

Source

pub fn as_bytes(&self) -> &[u8]

Returns the raw byte slice of the string contents.

Source

pub fn clear(&mut self)

Clears the string, setting its length to zero.

Does not release the backing allocation.

Source

pub fn find_byte(&self, byte: u8) -> Option<usize>

Returns the byte offset of the first occurrence of byte, or None.

Source

pub fn contains_byte(&self, byte: u8) -> bool

Returns true if the string contains the given byte.

Source

pub fn count_byte(&self, byte: u8) -> usize

Returns the number of times byte appears in the string.

Source

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.

Source

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' ').

Trait Implementations§

Source§

impl Debug for ExString<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ExString<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq<str> for ExString<'_>

Source§

fn eq(&self, other: &str) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq for ExString<'_>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Write for ExString<'_>

Source§

fn write_str(&mut self, s: &str) -> Result

Appends s to the string. Called by write! / writeln!.

1.1.0 · Source§

fn write_char(&mut self, c: char) -> Result<(), Error>

Writes a char into this writer, returning whether the write succeeded. Read more
1.0.0 · Source§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Glue for usage of the write! macro with implementors of this trait. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for ExString<'a>

§

impl<'a> !RefUnwindSafe for ExString<'a>

§

impl<'a> !Send for ExString<'a>

§

impl<'a> !Sync for ExString<'a>

§

impl<'a> Unpin for ExString<'a>

§

impl<'a> UnsafeUnpin for ExString<'a>

§

impl<'a> !UnwindSafe for ExString<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.