oxihuman_core/
text_buffer.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9pub struct TextBuffer {
10 buf: String,
11 append_count: u64,
12}
13
14#[allow(dead_code)]
15impl TextBuffer {
16 pub fn new() -> Self {
17 Self {
18 buf: String::new(),
19 append_count: 0,
20 }
21 }
22
23 pub fn with_capacity(cap: usize) -> Self {
24 Self {
25 buf: String::with_capacity(cap),
26 append_count: 0,
27 }
28 }
29
30 pub fn append(&mut self, s: &str) {
32 self.buf.push_str(s);
33 self.append_count += 1;
34 }
35
36 pub fn append_line(&mut self, s: &str) {
38 self.buf.push_str(s);
39 self.buf.push('\n');
40 self.append_count += 1;
41 }
42
43 pub fn char_count(&self) -> usize {
45 self.buf.chars().count()
46 }
47
48 pub fn byte_len(&self) -> usize {
50 self.buf.len()
51 }
52
53 pub fn is_empty(&self) -> bool {
54 self.buf.is_empty()
55 }
56
57 pub fn as_str(&self) -> &str {
59 &self.buf
60 }
61
62 pub fn line_count(&self) -> usize {
64 if self.buf.is_empty() {
65 return 0;
66 }
67 self.buf.lines().count()
68 }
69
70 pub fn line(&self, n: usize) -> Option<&str> {
72 self.buf.lines().nth(n)
73 }
74
75 pub fn lines_vec(&self) -> Vec<&str> {
77 self.buf.lines().collect()
78 }
79
80 pub fn find(&self, needle: &str) -> Option<usize> {
82 self.buf.find(needle)
83 }
84
85 pub fn count_occurrences(&self, needle: &str) -> usize {
87 if needle.is_empty() {
88 return 0;
89 }
90 let mut count = 0;
91 let mut start = 0;
92 while let Some(pos) = self.buf[start..].find(needle) {
93 count += 1;
94 start += pos + needle.len();
95 }
96 count
97 }
98
99 pub fn replace_all(&mut self, from: &str, to: &str) {
101 self.buf = self.buf.replace(from, to);
102 }
103
104 pub fn clear(&mut self) {
106 self.buf.clear();
107 }
108
109 pub fn truncate(&mut self, n: usize) {
111 if n < self.buf.len() {
112 let n_safe = (0..=n)
114 .rev()
115 .find(|&i| self.buf.is_char_boundary(i))
116 .unwrap_or(0);
117 self.buf.truncate(n_safe);
118 }
119 }
120
121 pub fn append_count(&self) -> u64 {
122 self.append_count
123 }
124}
125
126impl Default for TextBuffer {
127 fn default() -> Self {
128 Self::new()
129 }
130}
131
132pub fn new_text_buffer() -> TextBuffer {
133 TextBuffer::new()
134}
135
136pub fn tb_append(buf: &mut TextBuffer, s: &str) {
137 buf.append(s);
138}
139
140pub fn tb_append_line(buf: &mut TextBuffer, s: &str) {
141 buf.append_line(s);
142}
143
144pub fn tb_as_str(buf: &TextBuffer) -> &str {
145 buf.as_str()
146}
147
148pub fn tb_line_count(buf: &TextBuffer) -> usize {
149 buf.line_count()
150}
151
152pub fn tb_find(buf: &TextBuffer, needle: &str) -> Option<usize> {
153 buf.find(needle)
154}
155
156pub fn tb_clear(buf: &mut TextBuffer) {
157 buf.clear();
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163
164 #[test]
165 fn empty_on_creation() {
166 let b = new_text_buffer();
167 assert!(b.is_empty());
168 assert_eq!(b.byte_len(), 0);
169 }
170
171 #[test]
172 fn append_and_as_str() {
173 let mut b = new_text_buffer();
174 tb_append(&mut b, "hello");
175 tb_append(&mut b, " world");
176 assert_eq!(tb_as_str(&b), "hello world");
177 }
178
179 #[test]
180 fn append_line_adds_newline() {
181 let mut b = new_text_buffer();
182 tb_append_line(&mut b, "line1");
183 tb_append_line(&mut b, "line2");
184 assert_eq!(tb_line_count(&b), 2);
185 }
186
187 #[test]
188 fn line_access() {
189 let mut b = new_text_buffer();
190 tb_append_line(&mut b, "alpha");
191 tb_append_line(&mut b, "beta");
192 assert_eq!(b.line(0), Some("alpha"));
193 assert_eq!(b.line(1), Some("beta"));
194 assert_eq!(b.line(2), None);
195 }
196
197 #[test]
198 fn find_substring() {
199 let mut b = new_text_buffer();
200 tb_append(&mut b, "abcdef");
201 assert_eq!(tb_find(&b, "cde"), Some(2));
202 assert_eq!(tb_find(&b, "xyz"), None);
203 }
204
205 #[test]
206 fn count_occurrences() {
207 let mut b = new_text_buffer();
208 tb_append(&mut b, "aababab");
209 assert_eq!(b.count_occurrences("ab"), 3);
210 }
211
212 #[test]
213 fn replace_all() {
214 let mut b = new_text_buffer();
215 tb_append(&mut b, "foo bar foo");
216 b.replace_all("foo", "baz");
217 assert_eq!(tb_as_str(&b), "baz bar baz");
218 }
219
220 #[test]
221 fn clear_resets() {
222 let mut b = new_text_buffer();
223 tb_append(&mut b, "data");
224 tb_clear(&mut b);
225 assert!(b.is_empty());
226 }
227
228 #[test]
229 fn truncate() {
230 let mut b = new_text_buffer();
231 tb_append(&mut b, "hello world");
232 b.truncate(5);
233 assert_eq!(tb_as_str(&b), "hello");
234 }
235
236 #[test]
237 fn append_count() {
238 let mut b = new_text_buffer();
239 tb_append(&mut b, "a");
240 tb_append_line(&mut b, "b");
241 assert_eq!(b.append_count(), 2);
242 }
243}