Skip to main content

cheetah_string/
builder.rs

1use alloc::string::String;
2use core::fmt;
3
4use crate::CheetahString;
5
6/// Append-heavy builder for constructing Cheetah string values.
7///
8/// `CheetahBuilder` keeps mutable construction separate from immutable,
9/// clone-cheap [`CheetahString`] values.
10#[derive(Clone, Default)]
11pub struct CheetahBuilder {
12    inner: String,
13}
14
15impl CheetahBuilder {
16    /// Creates an empty builder.
17    #[inline]
18    pub fn new() -> Self {
19        Self {
20            inner: String::new(),
21        }
22    }
23
24    /// Creates an empty builder with at least `capacity` bytes.
25    #[inline]
26    pub fn with_capacity(capacity: usize) -> Self {
27        Self {
28            inner: String::with_capacity(capacity),
29        }
30    }
31
32    /// Creates a builder from existing owned storage.
33    #[inline]
34    pub fn from_string(value: String) -> Self {
35        Self { inner: value }
36    }
37
38    /// Appends a string slice.
39    #[inline]
40    pub fn push_str(&mut self, value: &str) {
41        self.inner.push_str(value);
42    }
43
44    /// Appends a character.
45    #[inline]
46    pub fn push(&mut self, value: char) {
47        self.inner.push(value);
48    }
49
50    /// Reserves capacity for at least `additional` more bytes.
51    #[inline]
52    pub fn reserve(&mut self, additional: usize) {
53        self.inner.reserve(additional);
54    }
55
56    /// Clears the current contents while preserving capacity.
57    #[inline]
58    pub fn clear(&mut self) {
59        self.inner.clear();
60    }
61
62    /// Returns the current contents.
63    #[inline]
64    pub fn as_str(&self) -> &str {
65        self.inner.as_str()
66    }
67
68    /// Returns the current length in bytes.
69    #[inline]
70    pub fn len(&self) -> usize {
71        self.inner.len()
72    }
73
74    /// Returns whether the builder is empty.
75    #[inline]
76    pub fn is_empty(&self) -> bool {
77        self.inner.is_empty()
78    }
79
80    /// Returns the allocated capacity in bytes.
81    #[inline]
82    pub fn capacity(&self) -> usize {
83        self.inner.capacity()
84    }
85
86    /// Freezes this builder into the canonical clone-cheap string value.
87    ///
88    /// Use [`CheetahBuilder::into_string`] when construction is followed by
89    /// more mutation or when spare capacity must be retained.
90    #[inline]
91    pub fn finish(self) -> CheetahString {
92        CheetahString::from_string(self.inner)
93    }
94
95    /// Freezes the builder into the canonical clone-cheap string value.
96    ///
97    /// This compatibility name is retained so downstream v2 consumers can
98    /// adopt the immutable v3 core without a source migration.
99    #[deprecated(since = "3.0.0", note = "use finish()")]
100    #[inline]
101    pub fn finish_string(self) -> CheetahString {
102        self.finish()
103    }
104
105    /// Returns the owned `String` backing this builder.
106    #[inline]
107    pub fn into_string(self) -> String {
108        self.inner
109    }
110}
111
112impl From<String> for CheetahBuilder {
113    #[inline]
114    fn from(value: String) -> Self {
115        Self::from_string(value)
116    }
117}
118
119impl From<&str> for CheetahBuilder {
120    #[inline]
121    fn from(value: &str) -> Self {
122        let mut builder = Self::with_capacity(value.len());
123        builder.push_str(value);
124        builder
125    }
126}
127
128impl Extend<char> for CheetahBuilder {
129    #[inline]
130    fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
131        self.inner.extend(iter);
132    }
133}
134
135impl<'a> Extend<&'a str> for CheetahBuilder {
136    #[inline]
137    fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
138        for item in iter {
139            self.push_str(item);
140        }
141    }
142}
143
144impl fmt::Debug for CheetahBuilder {
145    #[inline]
146    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147        f.debug_struct("CheetahBuilder")
148            .field("value", &self.inner)
149            .field("capacity", &self.inner.capacity())
150            .finish()
151    }
152}