uqa_core/memory/
string.rs1use super::{replacement, MemoryBudget, MemoryError, MemoryReservation};
10
11#[derive(Debug)]
12pub struct BudgetedString {
13 value: String,
14 memory: MemoryReservation,
15}
16
17impl BudgetedString {
18 pub fn new(budget: &MemoryBudget) -> Self {
19 Self {
20 value: String::new(),
21 memory: budget.empty_reservation(),
22 }
23 }
24
25 pub fn capacity(&self) -> usize {
26 self.value.capacity()
27 }
28
29 pub fn reserve(&mut self, additional: usize) -> Result<(), MemoryError> {
30 let required = self
31 .value
32 .len()
33 .checked_add(additional)
34 .ok_or(MemoryError::SizeOverflow)?;
35 if required <= self.capacity() {
36 return Ok(());
37 }
38 let (capacity, memory) =
39 replacement::<u8>(self.memory.budget(), self.capacity(), required)?;
40 let mut value = String::new();
41 value.try_reserve_exact(capacity)?;
42 value.push_str(&self.value);
43 self.value = value;
44 self.memory = memory;
45 Ok(())
46 }
47
48 pub fn push_str(&mut self, text: &str) -> Result<(), MemoryError> {
49 self.reserve(text.len())?;
50 self.value.push_str(text);
51 Ok(())
52 }
53
54 pub fn push(&mut self, character: char) -> Result<(), MemoryError> {
55 self.reserve(character.len_utf8())?;
56 self.value.push(character);
57 Ok(())
58 }
59
60 pub fn into_parts(self) -> (String, MemoryReservation) {
61 (self.value, self.memory)
62 }
63}
64
65impl std::ops::Deref for BudgetedString {
66 type Target = str;
67
68 fn deref(&self) -> &str {
69 &self.value
70 }
71}