cj_ascii/ascii_string.rs
1use crate::ascii_group::AsciiGroupIter;
2use crate::ascii_traits::{AsciiOrdToChar, CharToAsciiOrd};
3use std::borrow::Cow;
4use std::collections::vec_deque::{Iter, IterMut};
5use std::collections::VecDeque;
6use std::fmt;
7use std::fmt::{Debug, Display, Formatter};
8use std::io::{Read, Write};
9use std::iter::Map;
10use std::ops::{Add, AddAssign, Index, IndexMut};
11
12/// A String like struct that contains ASCII and Extended ASCII characters.
13/// <br>
14/// Because it accepts Extended ASCII, all u8 values are accepted.
15/// # samples
16/// ```
17/// use cj_ascii::prelude::*;
18///
19/// let mut astring = AsciiString::try_from("This is a test").unwrap();
20/// let mut astring2 = AsciiString::with_capacity(14);
21/// astring2 += "This";
22/// astring2 += " is";
23/// astring2 += " a";
24/// astring2 += " test";
25/// assert_eq!(astring, astring2);
26/// ```
27/// Mix of char, u8, &str and AsciiString concatenation.
28/// ```
29/// # use cj_ascii::prelude::*;
30/// let mut astring = AsciiString::new();
31/// astring += 'A';
32/// astring += 66;
33/// astring += "C";
34/// astring += "DEF";
35/// let astring2 = AsciiString::from(&astring);
36/// astring += astring2;
37/// assert_eq!(&astring.to_string(), "ABCDEFABCDEF");
38/// ```
39/// Indexing
40/// ```
41/// # use cj_ascii::prelude::*;
42/// let mut astring = AsciiString::new();
43/// astring += 'A';
44/// astring += 66;
45/// astring += "C";
46/// astring += "DEF";
47/// assert_eq!(astring[0], 'A'.ascii_ord_unchecked());
48/// assert_eq!(astring[1].to_ascii_char(), 'B');
49/// assert_eq!(astring[2], 67);
50/// assert_eq!(astring[3], 68);
51/// assert_eq!(astring[4], 69);
52/// assert_eq!(astring[5], 70);
53/// ```
54/// Indexing Mut
55/// ```
56/// # use cj_ascii::prelude::*;
57/// let mut astring = AsciiString::new();
58/// astring += "ABCDEF";
59/// astring[0] = 71;
60/// astring[1] = 'H'.ascii_ord_unchecked();
61/// astring[2] = 73;
62/// astring[3] = 74;
63/// astring[4] = 75;
64/// astring[5] = 76;
65/// assert_eq!(astring[0], 'G'.ascii_ord_unchecked());
66/// assert_eq!(astring.to_string(), "GHIJKL");
67/// ```
68/// Iteration
69/// ```
70/// # use cj_ascii::prelude::*;
71/// let mut astring = AsciiString::new();
72/// astring += "ABCDEF";
73/// let mut iter = astring.iter();
74/// assert_eq!(iter.next(), Some(&65));
75/// assert_eq!(iter.next(), Some(&66));
76/// assert_eq!(iter.next(), Some(&67));
77/// assert_eq!(iter.next(), Some(&68));
78/// assert_eq!(iter.next(), Some(&69));
79/// assert_eq!(iter.next(), Some(&70));
80/// assert_eq!(iter.next(), None);
81/// // or
82/// let mut iter = astring.iter();
83/// assert_eq!(iter.next(), Some(&'A'.ascii_ord_unchecked()));
84/// assert_eq!(iter.next(), Some(&'B'.ascii_ord_unchecked()));
85/// assert_eq!(iter.next(), Some(&'C'.ascii_ord_unchecked()));
86/// assert_eq!(iter.next(), Some(&'D'.ascii_ord_unchecked()));
87/// assert_eq!(iter.next(), Some(&'E'.ascii_ord_unchecked()));
88/// assert_eq!(iter.next(), Some(&'F'.ascii_ord_unchecked()));
89/// assert_eq!(iter.next(), None);
90/// ```
91/// Iteration Mut
92/// ```
93/// # use cj_ascii::prelude::*;
94/// let mut astring = AsciiString::new();
95/// astring += "ABCDEF";
96/// let mut iter = astring.iter_mut();
97/// for c in iter {
98/// *c = *c + 1;
99/// }
100/// assert_eq!(astring.to_string(), "BCDEFG");
101/// ```
102/// Iter Ascii
103/// ```
104/// # use cj_ascii::prelude::*;
105/// let mut astring = AsciiString::new();
106/// astring += "ABCDEF";
107/// let mut iter = astring.iter_ascii();
108/// assert_eq!(iter.next(), Some('A'));
109/// assert_eq!(iter.next(), Some('B'));
110/// assert_eq!(iter.next(), Some('C'));
111/// assert_eq!(iter.next(), Some('D'));
112/// assert_eq!(iter.next(), Some('E'));
113/// assert_eq!(iter.next(), Some('F'));
114/// assert_eq!(iter.next(), None);
115/// ```
116/// Iter AsciiGroup
117/// ```
118/// # use cj_ascii::prelude::*;
119/// let astring = AsciiString::try_from("Hello World!").unwrap();
120/// for x in astring.iter_ascii_group() {
121/// match x {
122/// AsciiGroup::PrintableCtrl(_) => println!("PrintableCtrl: {}", x.as_char()),
123/// AsciiGroup::Printable(_) => println!("PrintableAscii: {}", x.as_char()),
124/// AsciiGroup::NonPrintableCtrl(_) => println!("NonPrintableCtrl: {}", x.as_byte()),
125/// AsciiGroup::Extended(_) => println!("Extended: {}", x.as_byte()),
126/// }
127/// }
128/// ```
129/// Push
130/// ```
131/// # use cj_ascii::prelude::*;
132/// let mut astring = AsciiString::new();
133/// astring.push('A');
134/// astring.push(66);
135/// astring.push('C');
136/// astring.push('D');
137/// assert_eq!(astring.to_string(), "ABCD");
138/// astring.push_front('Z');
139/// astring.push_front(89);
140/// astring.push_front('X');
141/// assert_eq!(astring.to_string(), "XYZABCD");
142/// ```
143/// Try Push
144/// ```
145/// # use cj_ascii::prelude::*;
146/// let mut astring = AsciiString::new();
147/// astring.try_push('A').unwrap();
148/// astring.try_push(66).unwrap();
149/// astring.try_push('C').unwrap();
150/// astring.try_push('D').unwrap();
151/// assert!(astring.try_push('€').is_err());
152/// assert_eq!(astring.to_string(), "ABCD");
153///
154/// let mut astring = AsciiString::new();
155/// astring.try_push_front('A').unwrap();
156/// astring.try_push_front(66).unwrap();
157/// astring.try_push_front('C').unwrap();
158/// astring.try_push_front('D').unwrap();
159/// assert!(astring.try_push_front('€').is_err());
160/// assert_eq!(astring.to_string(), "DCBA");
161/// ```
162/// Push str
163/// ```
164/// # use cj_ascii::prelude::*;
165/// let mut astring = AsciiString::new();
166/// astring.push_str("ABC");
167/// astring.push_str("DEF");
168/// assert_eq!(astring.to_string(), "ABCDEF");
169/// ```
170/// Push str Lossy
171/// ```
172/// # use cj_ascii::prelude::*;
173/// let mut astring = AsciiString::new();
174/// astring.push_str_lossy("ABCD");
175/// astring.push_str_lossy("€");
176/// assert_eq!(astring.to_string(), "ABCD ");
177/// ```
178/// Invalid Ascii
179/// ```
180/// # use cj_ascii::prelude::*;
181/// let string = "ABC€";
182/// let result = AsciiString::try_from(string);
183/// assert!(result.is_err());
184/// ```
185
186#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
187pub struct AsciiString {
188 pub(crate) bytes: VecDeque<u8>,
189}
190
191impl AsciiString {
192 /// Creates a new empty `AsciiString` with the given capacity.
193 #[inline]
194 pub fn with_capacity(capacity: usize) -> Self {
195 Self {
196 bytes: VecDeque::with_capacity(capacity),
197 }
198 }
199 /// Creates a new empty `AsciiString`.
200 #[inline]
201 pub fn new() -> Self {
202 Self::default()
203 }
204 /// Returns the length of the `AsciiString` in bytes.
205 pub fn len(&self) -> usize {
206 self.bytes.len()
207 }
208 /// Returns true if the `AsciiString` contains no bytes.
209 pub fn is_empty(&self) -> bool {
210 self.bytes.is_empty()
211 }
212 /// Pushes a char or byte onto the end of the `AsciiString`.
213 /// # Panics
214 /// * If a char is supplied and is not ASCII/Extended ASCII.
215 /// * using byte (u8) will never panic.
216 /// # Examples
217 /// ```
218 /// # use cj_ascii::prelude::*;
219 /// let mut astring = AsciiString::new();
220 /// astring.push('A');
221 /// astring.push(66);
222 /// astring.push('C');
223 /// astring.push('D');
224 /// //astring.push('€'); // Will panic!
225 /// ```
226 pub fn push<T: CharToAsciiOrd>(&mut self, value: T) {
227 self.bytes.push_back(value.ascii_ord_unchecked());
228 }
229 /// Pushes a char or byte onto the end of the `AsciiString`.
230 /// # Errors
231 /// * If a char is supplied and is not ASCII/Extended ASCII.
232 /// * using byte (u8) will never error.
233 /// # Examples
234 /// ```
235 /// # use cj_ascii::prelude::*;
236 /// let mut astring = AsciiString::new();
237 /// astring.try_push('A').unwrap();
238 /// astring.try_push(66).unwrap();
239 /// astring.try_push('C').unwrap();
240 /// astring.try_push('D').unwrap();
241 /// assert!(astring.try_push('€').is_err());
242 /// ```
243 pub fn try_push<T: CharToAsciiOrd + Display>(&mut self, value: T) -> Result<(), String> {
244 self.bytes.push_back(value.try_ascii_ord()?);
245 Ok(())
246 }
247 /// Pops a byte from the end of the `AsciiString`.
248 pub fn pop(&mut self) -> Option<u8> {
249 self.bytes.pop_back()
250 }
251 /// Pushes a char or byte onto the front of the `AsciiString`.
252 /// # Panics
253 /// * If a char is supplied and is not ASCII/Extended ASCII.
254 /// * using byte (u8) will never panic.
255 /// # Examples
256 /// ```
257 /// # use cj_ascii::prelude::*;
258 /// let mut astring = AsciiString::new();
259 /// astring.push_front('A');
260 /// astring.push_front(66);
261 /// astring.push_front('C');
262 /// astring.push_front('D');
263 /// //astring.push_front('€'); // Will panic!
264 /// assert_eq!(astring.to_string(), "DCBA");
265 /// ```
266 pub fn push_front<T: CharToAsciiOrd>(&mut self, value: T) {
267 self.bytes.push_front(value.ascii_ord_unchecked());
268 }
269 /// Pushes a char or byte onto the front of the `AsciiString`.
270 /// # Errors
271 /// * If a char is supplied and is not ASCII/Extended ASCII.
272 /// * using byte (u8) will never error.
273 /// # Examples
274 /// ```
275 /// # use cj_ascii::prelude::*;
276 /// let mut astring = AsciiString::new();
277 /// astring.try_push_front('A').unwrap();
278 /// astring.try_push_front(66).unwrap();
279 /// astring.try_push_front('C').unwrap();
280 /// astring.try_push_front('D').unwrap();
281 /// assert!(astring.try_push_front('€').is_err());
282 /// assert_eq!(astring.to_string(), "DCBA");
283 /// ```
284 pub fn try_push_front<T: CharToAsciiOrd + Display>(&mut self, value: T) -> Result<(), String> {
285 self.bytes.push_front(value.try_ascii_ord()?);
286 Ok(())
287 }
288 /// Pops a byte from the front of the `AsciiString`.
289 pub fn pop_front(&mut self) -> Option<u8> {
290 self.bytes.pop_front()
291 }
292 /// Pushes a char onto the end of the `AsciiString`.
293 /// # Panics
294 /// * if the char is not ASCII/Extended ASCII.
295 /// # Examples
296 /// ```
297 /// # use cj_ascii::prelude::*;
298 /// let mut astring = AsciiString::new();
299 /// astring.push_char('A');
300 /// astring.push_char('B');
301 /// astring.push_char('C');
302 /// astring.push_char('D');
303 /// //astring.push_char('€'); // Will panic!
304 /// ```
305 pub fn push_char(&mut self, character: char) {
306 *self += character;
307 }
308 /// Pushes a char onto the end of the `AsciiString`.
309 /// # Errors
310 /// * if the char is not ASCII/Extended ASCII.
311 /// # Examples
312 /// ```
313 /// # use cj_ascii::prelude::*;
314 /// let mut astring = AsciiString::new();
315 /// astring.try_push_char('A').unwrap();
316 /// astring.try_push_char('B').unwrap();
317 /// astring.try_push_char('C').unwrap();
318 /// astring.try_push_char('D').unwrap();
319 /// assert!(astring.try_push_char('€').is_err());
320 /// ```
321 pub fn try_push_char(&mut self, character: char) -> Result<(), String> {
322 self.bytes.push_back(character.try_ascii_ord()?);
323 Ok(())
324 }
325 /// Pushes a char onto the front of the `AsciiString`.
326 /// # Panics
327 /// * if the char is not ASCII/Extended ASCII.
328 pub fn push_front_char(&mut self, character: char) {
329 self.bytes.push_front(character.ascii_ord_unchecked());
330 }
331 /// Pushes a char onto the front of the `AsciiString`.
332 /// # Errors
333 /// * if the char is not ASCII/Extended ASCII.
334 /// # Examples
335 /// ```
336 /// # use cj_ascii::prelude::*;
337 /// let mut astring = AsciiString::new();
338 /// astring.try_push_front_char('A').unwrap();
339 /// astring.try_push_front_char('B').unwrap();
340 /// astring.try_push_front_char('C').unwrap();
341 /// astring.try_push_front_char('D').unwrap();
342 /// assert!(astring.try_push_front_char('€').is_err());
343 /// assert_eq!(astring.to_string(), "DCBA");
344 /// ```
345 pub fn try_push_front_char(&mut self, character: char) -> Result<(), String> {
346 self.bytes.push_front(character.try_ascii_ord()?);
347 Ok(())
348 }
349 /// Pops a char from the end of the `AsciiString`.
350 pub fn pop_char(&mut self) -> Option<char> {
351 self.bytes.pop_back().map(|byte| byte.to_ascii_char())
352 }
353 /// Pops a char from the front of the `AsciiString`.
354 pub fn pop_front_char(&mut self) -> Option<char> {
355 self.bytes.pop_front().map(|byte| byte.to_ascii_char())
356 }
357 /// Pushes a string onto the end of the `AsciiString`.
358 /// # Panics
359 /// * if the string contains any non ASCII/Extended ASCII characters.
360 pub fn push_str(&mut self, string: &str) {
361 *self += string;
362 }
363 /// Pushes a string onto the end of the `AsciiString`.
364 /// # Errors
365 /// * if the string contains any non ASCII/Extended ASCII characters.
366 /// # Examples
367 /// ```
368 /// # use cj_ascii::prelude::*;
369 /// let mut astring = AsciiString::new();
370 /// astring.try_push_str("ABCD").unwrap();
371 /// assert!(astring.try_push_str("€").is_err());
372 /// ```
373 pub fn try_push_str(&mut self, string: &str) -> Result<(), String> {
374 let astr = AsciiString::try_from(string)?;
375 self.bytes.extend(astr.bytes);
376
377 Ok(())
378 }
379 /// Pushes a string onto the end of the `AsciiString`, replacing non ASCII/Extended ASCII characters with a space.
380 /// # Examples
381 /// ```
382 /// # use cj_ascii::prelude::*;
383 /// let mut astring = AsciiString::new();
384 /// astring.push_str_lossy("ABCD");
385 /// astring.push_str_lossy("€");
386 /// assert_eq!(astring.to_string(), "ABCD ");
387 /// ```
388 pub fn push_str_lossy(&mut self, string: &str) {
389 let str_len = string.len();
390 let my_remaining_capacity = self.remaining_capacity();
391 if str_len > my_remaining_capacity {
392 self.bytes.reserve(str_len - my_remaining_capacity);
393 }
394 for character in string.chars() {
395 self.push(character.ascii_ord_or(32));
396 }
397 }
398 /// Pushes an `AsciiString` onto the end of the `AsciiString`.
399 pub fn push_ascii_string(&mut self, string: &AsciiString) {
400 *self += string;
401 }
402
403 /// Pushes a slice of bytes onto the end of the `AsciiString`.
404 pub fn push_bytes(&mut self, bytes: &[u8]) {
405 self.bytes.extend(bytes);
406 }
407 /// Clears the `AsciiString`, removing all bytes.
408 #[inline]
409 pub fn clear(&mut self) {
410 self.bytes.clear();
411 }
412 /// Truncates the `AsciiString` to the given length.
413 pub fn truncate(&mut self, len: usize) {
414 self.bytes.truncate(len);
415 }
416 /// Returns the capacity of the `AsciiString` in bytes.
417 #[inline]
418 pub fn capacity(&self) -> usize {
419 self.bytes.capacity()
420 }
421 /// Returns the number of bytes remaining to full capacity.
422 pub fn remaining_capacity(&self) -> usize {
423 self.bytes.capacity() - self.bytes.len()
424 }
425 /// Reserves capacity for at least `additional` more bytes to be inserted in the given `AsciiString`.
426 pub fn reserve(&mut self, additional: usize) {
427 self.bytes.reserve(additional);
428 }
429 /// Reserves the minimum capacity for exactly `additional` more bytes to be inserted in the given `AsciiString`.
430 pub fn reserve_exact(&mut self, additional: usize) {
431 self.bytes.reserve_exact(additional);
432 }
433 /// Shrinks the capacity of the `AsciiString` to match its length.
434 pub fn shrink_to_fit(&mut self) {
435 self.bytes.shrink_to_fit();
436 }
437 /// Shrinks the capacity of the `AsciiString` to the given value.
438 pub fn shrink_to(&mut self, min_capacity: usize) {
439 self.bytes.shrink_to(min_capacity);
440 }
441 /// Returns a byte slice of the raw `AsciiString`.
442 ///
443 /// * Each byte represents a single char.
444 /// # note
445 /// * a mutable reference is required, but only to make the memory contiguous (if not contiguous already).
446 pub fn as_bytes(&mut self) -> &[u8] {
447 self.bytes.make_contiguous()
448 //self.bytes.as_slices().0
449 }
450 /// Returns a mutable byte slice of the raw `AsciiString`.
451 ///
452 /// * Each byte represents a single char.
453 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
454 self.bytes.make_contiguous()
455 //self.bytes.as_mut_slices().0
456 }
457
458 /// Fills buf with the contents of the `AsciiString`, returning the number of bytes read.
459 /// * this consumes the bytes read from the `AsciiString`.
460 /// # Example
461 ///```
462 /// # use cj_ascii::prelude::*;
463 /// let mut astring = AsciiString::new();
464 /// astring += "ABC";
465 /// let mut buf = [0u8; 3];
466 /// let result = astring.read(&mut buf);
467 ///
468 /// assert!(result.is_ok());
469 /// assert_eq!(result.unwrap(), 3);
470 /// assert_eq!(buf, [65, 66, 67]);
471 /// // astring is now empty
472 /// assert_eq!(astring.as_bytes(), []);
473 /// assert_eq!(astring.len(), 0);
474 /// ```
475 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
476 self.bytes.make_contiguous();
477 self.bytes.read(buf)
478 }
479 /// Writes buf into the `AsciiString`, returning the number of bytes written.
480 /// # Example
481 /// ```
482 /// # use cj_ascii::prelude::*;
483 /// let mut string = AsciiString::new();
484 /// let buf = [65, 66, 67];
485 /// let result = string.write(&buf);
486 ///
487 /// assert!(result.is_ok());
488 /// assert_eq!(result.unwrap(), 3);
489 /// assert_eq!(string.as_bytes(), [65, 66, 67]);
490 /// assert_eq!(string.len(), 3);
491 /// ```
492 #[inline]
493 pub fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
494 self.bytes.write(buf)
495 }
496 /// Sorts the `AsciiString` in place.
497 /// # Example
498 /// ```
499 /// # use cj_ascii::prelude::*;
500 /// let mut astring = AsciiString::try_from("DCBA").unwrap();
501 /// astring.sort();
502 /// assert_eq!(astring.to_string(), "ABCD");
503 /// ```
504 pub fn sort(&mut self) {
505 self.bytes.make_contiguous().sort_unstable();
506 }
507 /// Returns true if the `AsciiString` contains the given char or byte.
508 /// # Panics
509 /// * If a char is supplied and is not ASCII/Extended ASCII.
510 /// * using byte (u8) will never panic.
511 /// # Examples
512 /// ```
513 /// # use cj_ascii::prelude::*;
514 /// let mut astring = AsciiString::try_from("Hello World!").unwrap();
515 /// assert!(astring.contains('H'));
516 /// assert!(astring.contains(72));
517 /// // assert!(!astring.contains('€')); // Will panic!
518 pub fn contains<T: CharToAsciiOrd>(&self, value: T) -> bool {
519 self.bytes.contains(&value.ascii_ord_unchecked())
520 }
521 /// Returns a u8 iterator over the `AsciiString`.
522 /// # Examples
523 /// ```
524 /// # use cj_ascii::prelude::*;
525 /// let astring = AsciiString::try_from("Hello World!").unwrap();
526 /// let mut iter = astring.iter();
527 /// assert_eq!(iter.next(), Some(&72));
528 /// assert_eq!(iter.next(), Some(&101));
529 /// assert_eq!(iter.next(), Some(&108));
530 /// assert_eq!(iter.next(), Some(&108));
531 /// assert_eq!(iter.next(), Some(&111));
532 /// assert_eq!(iter.next(), Some(&32));
533 /// assert_eq!(iter.next(), Some(&87));
534 /// assert_eq!(iter.next(), Some(&111));
535 /// assert_eq!(iter.next(), Some(&114));
536 /// assert_eq!(iter.next(), Some(&108));
537 /// assert_eq!(iter.next(), Some(&100));
538 /// assert_eq!(iter.next(), Some(&33));
539 /// assert_eq!(iter.next(), None);
540 /// ```
541 #[inline]
542 pub fn iter(&self) -> Iter<u8> {
543 self.bytes.iter()
544 }
545
546 /// Returns a mutable u8 iterator over the `AsciiString`.
547 /// # Examples
548 /// ```
549 /// # use cj_ascii::prelude::*;
550 /// let mut astring = AsciiString::try_from("Hello World!").unwrap();
551 /// let mut iter = astring.iter_mut();
552 /// assert_eq!(iter.next(), Some(&mut 72));
553 /// assert_eq!(iter.next(), Some(&mut 101));
554 /// assert_eq!(iter.next(), Some(&mut 108));
555 /// assert_eq!(iter.next(), Some(&mut 108));
556 /// assert_eq!(iter.next(), Some(&mut 111));
557 /// assert_eq!(iter.next(), Some(&mut 32));
558 /// assert_eq!(iter.next(), Some(&mut 87));
559 /// assert_eq!(iter.next(), Some(&mut 111));
560 /// assert_eq!(iter.next(), Some(&mut 114));
561 /// assert_eq!(iter.next(), Some(&mut 108));
562 /// assert_eq!(iter.next(), Some(&mut 100));
563 /// assert_eq!(iter.next(), Some(&mut 33));
564 /// assert_eq!(iter.next(), None);
565 /// ```
566 /// ```
567 /// # use cj_ascii::prelude::*;
568 /// let mut astring = AsciiString::try_from("Hello World!").unwrap();
569 /// for byte in astring.iter_mut() {
570 /// if *byte == 32 {
571 /// *byte = 95;
572 /// }
573 /// }
574 /// assert_eq!(astring, AsciiString::try_from("Hello_World!").unwrap());
575 /// ```
576 #[inline]
577 pub fn iter_mut(&mut self) -> IterMut<u8> {
578 self.bytes.iter_mut()
579 }
580
581 /// Returns a char iterator over the `AsciiString`.
582 /// # Examples
583 /// ```
584 /// # use cj_ascii::prelude::*;
585 /// let astring = AsciiString::try_from("Hello World!").unwrap();
586 /// let mut iter = astring.iter_ascii();
587 /// assert_eq!(iter.next(), Some('H'));
588 /// assert_eq!(iter.next(), Some('e'));
589 /// assert_eq!(iter.next(), Some('l'));
590 /// assert_eq!(iter.next(), Some('l'));
591 /// assert_eq!(iter.next(), Some('o'));
592 /// assert_eq!(iter.next(), Some(' '));
593 /// assert_eq!(iter.next(), Some('W'));
594 /// assert_eq!(iter.next(), Some('o'));
595 /// assert_eq!(iter.next(), Some('r'));
596 /// assert_eq!(iter.next(), Some('l'));
597 /// assert_eq!(iter.next(), Some('d'));
598 /// assert_eq!(iter.next(), Some('!'));
599 /// assert_eq!(iter.next(), None);
600 /// ```
601 #[inline]
602 pub fn iter_ascii(&self) -> Map<Iter<'_, u8>, fn(&u8) -> char> {
603 self.bytes.iter().map(|byte| byte.to_ascii_char())
604 }
605 /// Returns an AsciiGroup iterator over the `AsciiString`.
606 /// # Examples
607 /// ```
608 /// # use cj_ascii::prelude::*;
609 /// let astring = AsciiString::try_from("Hello World!").unwrap();
610 /// for x in astring.iter_ascii_group() {
611 /// match x {
612 /// AsciiGroup::PrintableCtrl(_) => println!("PrintableCtrl: {}", x.as_char()),
613 /// AsciiGroup::Printable(_) => println!("PrintableAscii: {}", x.as_char()),
614 /// AsciiGroup::NonPrintableCtrl(_) => println!("NonPrintableCtrl: {}", x.as_byte()),
615 /// AsciiGroup::Extended(_) => println!("Extended: {}", x.as_byte()),
616 /// }
617 /// }
618 /// ```
619 #[inline]
620 pub fn iter_ascii_group(&self) -> AsciiGroupIter {
621 let iter = self.iter();
622 AsciiGroupIter::new(iter)
623 }
624}
625
626impl Index<usize> for AsciiString {
627 type Output = u8;
628 #[inline]
629 fn index(&self, index: usize) -> &Self::Output {
630 &self.bytes[index]
631 }
632}
633
634impl IndexMut<usize> for AsciiString {
635 #[inline]
636 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
637 &mut self.bytes[index]
638 }
639}
640
641impl Add<AsciiString> for AsciiString {
642 type Output = Self;
643
644 /// Concatenates two `AsciiString`s.
645 #[inline(always)]
646 fn add(mut self, rhs: AsciiString) -> Self::Output {
647 self.bytes.extend(rhs.bytes);
648 self
649 }
650}
651
652impl Add<&AsciiString> for AsciiString {
653 type Output = Self;
654
655 /// Concatenates two `AsciiString`s.
656 #[inline(always)]
657 fn add(mut self, rhs: &AsciiString) -> Self::Output {
658 self.bytes.extend(&rhs.bytes);
659 self
660 }
661}
662
663impl Add<String> for AsciiString {
664 type Output = Self;
665
666 /// Concatenates an `AsciiString` and a `String`.
667 /// # Panics
668 /// Panics if the `String` contains non-ASCII/Extended ASCII characters.
669 #[inline(always)]
670 fn add(mut self, rhs: String) -> Self::Output {
671 let rhs: Self = rhs.try_into().unwrap();
672 self.bytes.extend(rhs.bytes);
673 self
674 }
675}
676
677impl Add<&String> for AsciiString {
678 type Output = Self;
679
680 /// Concatenates an `AsciiString` and a `&String`.
681 /// # Panics
682 /// Panics if the `String` contains non-ASCII/Extended ASCII characters.
683 #[inline(always)]
684 fn add(mut self, rhs: &String) -> Self::Output {
685 let rhs: Self = rhs.try_into().unwrap();
686 self.bytes.extend(rhs.bytes);
687 self
688 }
689}
690
691impl Add<&str> for AsciiString {
692 type Output = Self;
693
694 /// Concatenates an `AsciiString` and a `&str`.
695 /// # Panics
696 /// Panics if the `str` contains non-ASCII/Extended ASCII characters.
697 #[inline(always)]
698 fn add(mut self, rhs: &str) -> Self::Output {
699 let rhs: Self = rhs.try_into().unwrap();
700 self.bytes.extend(rhs.bytes);
701 self
702 }
703}
704
705impl Add<char> for AsciiString {
706 type Output = Self;
707 /// Concatenates an `AsciiString` and a `char`.
708 /// # Panics
709 /// Panics if the `char` is not ASCII/Extended ASCII.
710 #[inline(always)]
711 fn add(mut self, rhs: char) -> Self::Output {
712 self.bytes.push_back(rhs.ascii_ord_unchecked());
713 self
714 }
715}
716
717impl Add<&char> for AsciiString {
718 type Output = Self;
719 /// Concatenates an `AsciiString` and a `&char`.
720 /// # Panics
721 /// Panics if the `char` is not ASCII/Extended ASCII.
722 #[inline(always)]
723 fn add(mut self, rhs: &char) -> Self::Output {
724 self.bytes.push_back(rhs.ascii_ord_unchecked());
725 self
726 }
727}
728
729impl AddAssign<AsciiString> for AsciiString {
730 #[inline(always)]
731 fn add_assign(&mut self, rhs: AsciiString) {
732 self.bytes.extend(rhs.bytes);
733 }
734}
735
736impl AddAssign<&AsciiString> for AsciiString {
737 #[inline(always)]
738 fn add_assign(&mut self, rhs: &AsciiString) {
739 self.bytes.extend(&rhs.bytes);
740 }
741}
742
743impl AddAssign<&str> for AsciiString {
744 /// Concatenates an `AsciiString` and a `&str`.
745 /// # Panics
746 /// Panics if the `str` contains non-ASCII/Extended ASCII characters.
747 #[inline(always)]
748 fn add_assign(&mut self, rhs: &str) {
749 let rhs = AsciiString::try_from(rhs).unwrap();
750 self.bytes.extend(rhs.bytes);
751 }
752}
753
754impl AddAssign<String> for AsciiString {
755 /// Concatenates an `AsciiString` and a `String`.
756 /// # Panics
757 /// Panics if the `String` contains non-ASCII/Extended ASCII characters.
758 #[inline(always)]
759 fn add_assign(&mut self, rhs: String) {
760 let rhs = AsciiString::try_from(rhs).unwrap();
761 self.bytes.extend(rhs.bytes);
762 }
763}
764
765impl AddAssign<char> for AsciiString {
766 /// Concatenates an `AsciiString` and a `char`.
767 /// # Panics
768 /// Panics if the `char` is not ASCII/Extended ASCII.
769 #[inline(always)]
770 fn add_assign(&mut self, rhs: char) {
771 self.bytes.push_back(rhs.ascii_ord_unchecked());
772 }
773}
774
775impl AddAssign<&char> for AsciiString {
776 /// Concatenates an `AsciiString` and a `&char`.
777 /// # Panics
778 /// Panics if the `char` is not ASCII/Extended ASCII.
779 #[inline(always)]
780 fn add_assign(&mut self, rhs: &char) {
781 self.bytes.push_back(rhs.ascii_ord_unchecked());
782 }
783}
784
785impl AddAssign<u8> for AsciiString {
786 #[inline(always)]
787 fn add_assign(&mut self, rhs: u8) {
788 self.bytes.push_back(rhs);
789 }
790}
791
792impl From<AsciiString> for String {
793 fn from(value: AsciiString) -> Self {
794 let mut result = String::with_capacity(value.bytes.len());
795 for byte in value.bytes {
796 result.push(byte.to_ascii_char());
797 }
798 result
799 }
800}
801
802impl From<&AsciiString> for String {
803 fn from(value: &AsciiString) -> Self {
804 let mut result = String::with_capacity(value.bytes.len());
805 for byte in &value.bytes {
806 result.push(byte.to_ascii_char());
807 }
808 result
809 }
810}
811
812impl From<&AsciiString> for AsciiString {
813 fn from(value: &AsciiString) -> Self {
814 let mut result = Self::with_capacity(value.bytes.len());
815 for byte in &value.bytes {
816 result.bytes.push_back(*byte);
817 }
818 result
819 }
820}
821
822// impl From<String> for AsciiString {
823// fn from(value: String) -> Self {
824// let mut result = Self::with_capacity(value.len());
825// for character in value.chars() {
826// result.bytes.push_back(character.ascii_ord_unchecked());
827// }
828// result
829// }
830// }
831
832impl TryFrom<String> for AsciiString {
833 type Error = String;
834
835 fn try_from(value: String) -> Result<Self, Self::Error> {
836 let mut result = Self::with_capacity(value.len());
837 for (inx, character) in value.chars().enumerate() {
838 if let Some(character) = character.ascii_ord() {
839 result.bytes.push_back(character);
840 } else {
841 return Err(format!(
842 r#"Non-ASCII character "{character}" found at index {inx}"#
843 ));
844 }
845 }
846 Ok(result)
847 }
848}
849
850// impl From<&str> for AsciiString {
851// fn from(value: &str) -> Self {
852// let mut result = Self::with_capacity(value.len());
853// for character in value.chars() {
854// // result.bytes.push_back(character.ascii_ord_unchecked());
855// result
856// .bytes
857// .push_back(character.ascii_ord().expect("Non-ASCII character found"));
858// }
859// result
860// }
861// }
862
863impl TryFrom<&str> for AsciiString {
864 type Error = String;
865
866 fn try_from(value: &str) -> Result<Self, Self::Error> {
867 let mut result = Self::with_capacity(value.len());
868 for (inx, character) in value.chars().enumerate() {
869 if let Some(character) = character.ascii_ord() {
870 result.bytes.push_back(character);
871 } else {
872 return Err(format!(
873 r#"Non-ASCII character "{character}" found at index {inx}"#
874 ));
875 }
876 }
877 Ok(result)
878 }
879}
880
881// impl From<&String> for AsciiString {
882// fn from(value: &String) -> Self {
883// let mut result = Self::with_capacity(value.len());
884// for character in value.chars() {
885// result.bytes.push_back(character.ascii_ord_unchecked());
886// }
887// result
888// }
889// }
890
891impl TryFrom<&String> for AsciiString {
892 type Error = String;
893
894 fn try_from(value: &String) -> Result<Self, Self::Error> {
895 let mut result = Self::with_capacity(value.len());
896 for (inx, character) in value.chars().enumerate() {
897 if let Some(character) = character.ascii_ord() {
898 result.bytes.push_back(character);
899 } else {
900 return Err(format!(
901 r#"Non-ASCII character "{character}" found at index {inx}"#
902 ));
903 }
904 }
905 Ok(result)
906 }
907}
908
909impl TryFrom<Cow<'_, str>> for AsciiString {
910 type Error = String;
911
912 fn try_from(value: Cow<str>) -> Result<Self, Self::Error> {
913 let mut result = Self::with_capacity(value.len());
914 for (inx, character) in value.chars().enumerate() {
915 if let Some(character) = character.ascii_ord() {
916 result.bytes.push_back(character);
917 } else {
918 return Err(format!(
919 r#"Non-ASCII character "{character}" found at index {inx}"#
920 ));
921 }
922 }
923 Ok(result)
924 }
925}
926
927impl From<&AsciiString> for Vec<u8> {
928 fn from(value: &AsciiString) -> Self {
929 value.bytes.clone().into()
930 }
931}
932
933impl From<AsciiString> for Vec<u8> {
934 #[inline]
935 fn from(value: AsciiString) -> Self {
936 value.bytes.into()
937 }
938}
939
940impl From<&AsciiString> for VecDeque<u8> {
941 fn from(value: &AsciiString) -> Self {
942 value.bytes.clone()
943 }
944}
945
946impl From<AsciiString> for VecDeque<u8> {
947 #[inline]
948 fn from(value: AsciiString) -> Self {
949 value.bytes
950 }
951}
952
953impl From<&AsciiString> for Vec<char> {
954 fn from(value: &AsciiString) -> Self {
955 let mut result = Vec::with_capacity(value.bytes.len());
956 for byte in &value.bytes {
957 result.push(byte.to_ascii_char());
958 }
959 result
960 }
961}
962
963impl From<AsciiString> for Vec<char> {
964 fn from(value: AsciiString) -> Self {
965 let mut result = Vec::with_capacity(value.bytes.len());
966 for byte in value.bytes {
967 result.push(byte.to_ascii_char());
968 }
969 result
970 }
971}
972
973impl From<&AsciiString> for VecDeque<char> {
974 fn from(value: &AsciiString) -> Self {
975 let mut result = VecDeque::with_capacity(value.bytes.len());
976 for byte in &value.bytes {
977 result.push_back(byte.to_ascii_char());
978 }
979 result
980 }
981}
982
983impl From<AsciiString> for VecDeque<char> {
984 fn from(value: AsciiString) -> Self {
985 let mut result = VecDeque::with_capacity(value.bytes.len());
986 for byte in value.bytes {
987 result.push_back(byte.to_ascii_char());
988 }
989 result
990 }
991}
992
993impl From<VecDeque<u8>> for AsciiString {
994 #[inline]
995 fn from(value: VecDeque<u8>) -> Self {
996 Self { bytes: value }
997 }
998}
999
1000impl From<Vec<u8>> for AsciiString {
1001 #[inline]
1002 fn from(value: Vec<u8>) -> Self {
1003 Self {
1004 bytes: value.into(),
1005 }
1006 }
1007}
1008
1009impl From<&[u8]> for AsciiString {
1010 fn from(value: &[u8]) -> Self {
1011 let mut result = Self::with_capacity(value.len());
1012 result.bytes.extend(value.iter());
1013 result
1014 }
1015}
1016
1017// impl From<char> for AsciiString {
1018// fn from(value: char) -> Self {
1019// let mut result = Self::with_capacity(1);
1020// result.bytes.push_back(value.ascii_ord_unchecked());
1021// result
1022// }
1023// }
1024
1025impl TryFrom<char> for AsciiString {
1026 type Error = String;
1027
1028 fn try_from(value: char) -> Result<Self, Self::Error> {
1029 let mut result = Self::with_capacity(1);
1030
1031 if let Some(character) = value.ascii_ord() {
1032 result.bytes.push_back(character);
1033 } else {
1034 return Err(format!(r#"Non-ASCII character "{value}" found"#));
1035 }
1036
1037 Ok(result)
1038 }
1039}
1040
1041impl TryFrom<&char> for AsciiString {
1042 type Error = String;
1043
1044 fn try_from(value: &char) -> Result<Self, Self::Error> {
1045 let mut result = Self::with_capacity(1);
1046
1047 if let Some(character) = value.ascii_ord() {
1048 result.bytes.push_back(character);
1049 } else {
1050 return Err(format!(r#"Non-ASCII character "{value}" found"#));
1051 }
1052
1053 Ok(result)
1054 }
1055}
1056
1057impl Display for AsciiString {
1058 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1059 for byte in &self.bytes {
1060 write!(f, "{}", byte.to_ascii_char())?;
1061 }
1062 Ok(())
1063 }
1064}
1065
1066impl Debug for AsciiString {
1067 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1068 for byte in &self.bytes {
1069 write!(f, "{}", byte.to_ascii_char())?;
1070 }
1071 Ok(())
1072 }
1073}
1074
1075//#[cfg(feature = "serde")]
1076//use serde::ser::SerializeSeq;
1077#[cfg(feature = "serde")]
1078use serde::{Deserialize, Deserializer, Serialize, Serializer};
1079
1080#[cfg(feature = "serde")]
1081impl Serialize for AsciiString {
1082 // fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1083 // let mut seq = serializer.serialize_seq(Some(self.bytes.len()))?;
1084 // for byte in &self.bytes {
1085 // seq.serialize_element(byte)?;
1086 // }
1087 // seq.end()
1088 // }
1089 // still thinking about this.
1090 // this works for stringly type serialization (to json,yaml etc), but binary serialization (raw bytes) should use self.as_bytes directly
1091 // since it's already serialized as a sequence of bytes.
1092 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1093 serializer.serialize_str(&String::from(self))
1094 }
1095}
1096
1097#[cfg(feature = "serde")]
1098impl<'de> Deserialize<'de> for AsciiString {
1099 // fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1100 // let bytes = VecDeque::deserialize(deserializer)?;
1101 // Ok(Self { bytes })
1102 // }
1103 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1104 let string = String::deserialize(deserializer)?;
1105 //Ok(Self::try_from(string)?)
1106 let result = Self::try_from(string);
1107 match result {
1108 Ok(value) => Ok(value),
1109 Err(error) => Err(serde::de::Error::custom(error)),
1110 }
1111 }
1112}
1113
1114#[cfg(test)]
1115mod test {
1116 use super::*;
1117
1118 #[test]
1119 fn test_add_ascii_string() {
1120 use crate::ascii_string::AsciiString;
1121 let mut string = AsciiString::with_capacity(3);
1122 string.push(65);
1123 string.push(66);
1124 string.push(67);
1125 let mut string2 = AsciiString::with_capacity(3);
1126 string2.push(68);
1127 string2.push(69);
1128 string2.push(70);
1129 let result = string + string2;
1130 assert_eq!(result.bytes.len(), 6);
1131 assert_eq!(result.bytes[0], 65);
1132 assert_eq!(result.bytes[1], 66);
1133 assert_eq!(result.bytes[2], 67);
1134 assert_eq!(result.bytes[3], 68);
1135 assert_eq!(result.bytes[4], 69);
1136 assert_eq!(result.bytes[5], 70);
1137 }
1138
1139 #[test]
1140 fn test_add_chars() {
1141 use crate::ascii_string::AsciiString;
1142 let mut string = AsciiString::with_capacity(3);
1143 string.push('A');
1144 string.push('B');
1145 string.push('C');
1146 let result = string + 'D';
1147 assert_eq!(result.bytes.len(), 4);
1148 assert_eq!(result.bytes[0], 65);
1149 assert_eq!(result.bytes[1], 66);
1150 assert_eq!(result.bytes[2], 67);
1151 assert_eq!(result.bytes[3], 68);
1152 }
1153
1154 #[test]
1155 fn test_from_ascii_string() {
1156 use crate::ascii_string::AsciiString;
1157 let mut string = AsciiString::with_capacity(3);
1158 string.push(65);
1159 string.push(66);
1160 string.push(67);
1161 let result = String::from(&string);
1162 assert_eq!(result.len(), 3);
1163 assert_eq!(result.chars().next().unwrap(), 'A');
1164 assert_eq!(result.chars().nth(1).unwrap(), 'B');
1165 assert_eq!(result.chars().nth(2).unwrap(), 'C');
1166 }
1167
1168 #[test]
1169 fn test_from_string() {
1170 use crate::ascii_string::AsciiString;
1171 let string = String::from("ABC");
1172 let result = AsciiString::try_from(&string).unwrap();
1173 assert_eq!(result.bytes.len(), 3);
1174 assert_eq!(result.bytes[0], 65);
1175 assert_eq!(result.bytes[1], 66);
1176 assert_eq!(result.bytes[2], 67);
1177 }
1178
1179 #[test]
1180 fn test_from_str() {
1181 use crate::ascii_string::AsciiString;
1182 let string = "ABC";
1183 let result = AsciiString::try_from(string).unwrap();
1184 assert_eq!(result.bytes.len(), 3);
1185 assert_eq!(result.bytes[0], 65);
1186 assert_eq!(result.bytes[1], 66);
1187 assert_eq!(result.bytes[2], 67);
1188 }
1189
1190 #[test]
1191 fn test_try_from_str() {
1192 use crate::ascii_string::AsciiString;
1193 let string = "ABC";
1194 let result = AsciiString::try_from(string);
1195 assert!(result.is_ok());
1196 let result = result.unwrap();
1197 assert_eq!(result.bytes.len(), 3);
1198 assert_eq!(result.bytes[0], 65);
1199 assert_eq!(result.bytes[1], 66);
1200 assert_eq!(result.bytes[2], 67);
1201 }
1202
1203 #[test]
1204 fn test_try_from_cow_string() {
1205 use crate::ascii_string::AsciiString;
1206 let cstring = Cow::from("ABC".to_string());
1207 let result = AsciiString::try_from(cstring);
1208 assert!(result.is_ok());
1209 let result = result.unwrap();
1210 assert_eq!(result.bytes.len(), 3);
1211 assert_eq!(result.bytes[0], 65);
1212 assert_eq!(result.bytes[1], 66);
1213 assert_eq!(result.bytes[2], 67);
1214 }
1215
1216 #[test]
1217 fn test_try_from_str_err() {
1218 use crate::ascii_string::AsciiString;
1219 let string = "ABC€";
1220 let result = AsciiString::try_from(string);
1221 assert!(result.is_err());
1222 }
1223
1224 #[test]
1225 fn test_add_assign_str() {
1226 use crate::ascii_string::AsciiString;
1227 let mut string = AsciiString::with_capacity(3);
1228 string += "ABC"; //.into();
1229 string += "DEF"; //.into();
1230 assert_eq!(&string.to_string(), "ABCDEF");
1231 }
1232
1233 #[test]
1234 fn test_assign_str() {
1235 use crate::ascii_string::AsciiString;
1236 let mut string = AsciiString::with_capacity(3);
1237 string += "ABC";
1238 assert_eq!(&string.to_string(), "ABC");
1239 }
1240
1241 #[test]
1242 fn test_add_assign_char() {
1243 use crate::ascii_string::AsciiString;
1244 let mut string = AsciiString::with_capacity(3);
1245 string += 'A';
1246 string += 'B';
1247 string += 'C';
1248 assert_eq!(&string.to_string(), "ABC");
1249 }
1250
1251 #[test]
1252 fn test_add_assign_byte() {
1253 use crate::ascii_string::AsciiString;
1254 let mut string = AsciiString::with_capacity(3);
1255 string += 65;
1256 string += 66;
1257 string += 67;
1258 assert_eq!(&string.to_string(), "ABC");
1259 }
1260
1261 #[test]
1262 fn test_add_assign_various() {
1263 use crate::ascii_string::AsciiString;
1264 let mut string = AsciiString::new();
1265 string += 'A';
1266 string += 66;
1267 string += "C";
1268 string += "DEF";
1269 let string2 = AsciiString::from(&string);
1270 string += string2;
1271 assert_eq!(&string.to_string(), "ABCDEFABCDEF");
1272 }
1273
1274 #[test]
1275 fn test_sort() {
1276 use crate::ascii_string::AsciiString;
1277 let mut string = AsciiString::with_capacity(3);
1278 string += "CBA";
1279 string.sort();
1280 assert_eq!(&string.to_string(), "ABC");
1281 }
1282
1283 #[test]
1284 fn test_index() {
1285 use crate::ascii_string::AsciiString;
1286 let mut string = AsciiString::with_capacity(3);
1287 string += "ABC";
1288 assert_eq!(string[0], 65);
1289 assert_eq!(string[1], 66);
1290 assert_eq!(string[2], 67);
1291 }
1292
1293 #[test]
1294 fn test_index_mut() {
1295 use crate::ascii_string::AsciiString;
1296 let mut string = AsciiString::with_capacity(3);
1297 string += "ABC";
1298 string[0] = 'D'.ascii_ord_unchecked();
1299 string[1] = 'E'.ascii_ord_unchecked();
1300 string[2] = 'F'.ascii_ord_unchecked();
1301 assert_eq!(string[0], 68);
1302 assert_eq!(string[1], 69);
1303 assert_eq!(string[2], 70);
1304 }
1305
1306 #[test]
1307 fn test_equals() {
1308 use crate::ascii_string::AsciiString;
1309 let mut string = AsciiString::with_capacity(3);
1310 string += "ABC";
1311 let mut string2 = AsciiString::with_capacity(3);
1312 string2 += "ABC";
1313 assert_eq!(string, string2);
1314 }
1315
1316 #[test]
1317 fn test_equals_string() {
1318 use crate::ascii_string::AsciiString;
1319 let mut string = AsciiString::with_capacity(3);
1320 string += "ABC";
1321 let string2: String = "ABC".to_string();
1322 let r = string2 == string.to_string();
1323 assert!(r);
1324 }
1325
1326 #[test]
1327 fn test_contains() {
1328 use crate::ascii_string::AsciiString;
1329 let mut string = AsciiString::with_capacity(3);
1330 string += "ABC";
1331 assert!(string.contains('A'));
1332 assert!(string.contains('B'));
1333 assert!(string.contains('C'));
1334 assert!(!string.contains('D'));
1335 }
1336
1337 #[test]
1338 fn test_read() {
1339 use crate::ascii_string::AsciiString;
1340 let mut string = AsciiString::new();
1341 string += "ABC";
1342 let mut buf = [0u8; 3];
1343 let result = string.read(&mut buf);
1344 assert!(result.is_ok());
1345 assert_eq!(result.unwrap(), 3);
1346 assert_eq!(buf, [65, 66, 67]);
1347 assert_eq!(string.as_bytes(), []);
1348 assert_eq!(string.len(), 0);
1349 }
1350
1351 #[test]
1352 fn test_read_undersized() {
1353 use crate::ascii_string::AsciiString;
1354 let mut string = AsciiString::new();
1355 string += "ABC";
1356 let mut buf = [0u8; 2];
1357 let result = string.read(&mut buf);
1358 assert!(result.is_ok());
1359 assert_eq!(result.unwrap(), 2);
1360 assert_eq!(buf, [65, 66]);
1361 assert_eq!(string.as_bytes(), [67]);
1362 assert_eq!(string.len(), 1);
1363
1364 buf.fill(0);
1365 let result = string.read(&mut buf);
1366 assert!(result.is_ok());
1367 assert_eq!(result.unwrap(), 1);
1368 assert_eq!(buf, [67, 0]);
1369 assert_eq!(string.as_bytes(), []);
1370 assert_eq!(string.len(), 0);
1371
1372 buf.fill(0);
1373 let result = string.read(&mut buf);
1374 assert!(result.is_ok());
1375 assert_eq!(result.unwrap(), 0);
1376 assert_eq!(buf, [0, 0]);
1377 assert_eq!(string.as_bytes(), []);
1378 assert_eq!(string.len(), 0);
1379 }
1380
1381 #[test]
1382 fn test_read_oversized() {
1383 use crate::ascii_string::AsciiString;
1384 let mut string = AsciiString::new();
1385 string += "ABC";
1386 let mut buf = [0u8; 4];
1387 let result = string.read(&mut buf);
1388 assert!(result.is_ok());
1389 assert_eq!(result.unwrap(), 3);
1390 assert_eq!(buf, [65, 66, 67, 0]);
1391 assert_eq!(string.as_bytes(), []);
1392 assert_eq!(string.len(), 0);
1393 }
1394
1395 #[test]
1396 fn test_write() {
1397 use crate::ascii_string::AsciiString;
1398 let mut string = AsciiString::new();
1399 let buf = [65, 66, 67];
1400 let result = string.write(&buf);
1401 assert!(result.is_ok());
1402 assert_eq!(result.unwrap(), 3);
1403 assert_eq!(string.as_bytes(), [65, 66, 67]);
1404 assert_eq!(string.len(), 3);
1405 }
1406
1407 #[test]
1408 fn test_iter_mut() {
1409 use crate::ascii_string::AsciiString;
1410 let mut string = AsciiString::with_capacity(3);
1411 string += "ABC";
1412 for c in string.iter_mut() {
1413 *c = 'D'.ascii_ord_unchecked();
1414 }
1415 assert_eq!(&string.to_string(), "DDD");
1416 }
1417
1418 #[test]
1419 fn test_ascii_group_iter() {
1420 use crate::ascii_string::AsciiString;
1421 let mut string = AsciiString::with_capacity(256);
1422 for i in 0..=255 {
1423 string += i;
1424 }
1425
1426 let mut c = 0u8;
1427 for x in string.iter_ascii_group() {
1428 assert_eq!(x.as_byte(), c);
1429 assert_eq!(x.as_char(), c.to_ascii_char());
1430
1431 c = c.saturating_add(1);
1432 }
1433 }
1434
1435 #[cfg(feature = "serde")]
1436 #[test]
1437 fn test_serde() {
1438 use crate::ascii_string::AsciiString;
1439 let mut string = AsciiString::with_capacity(3);
1440 string += "ABC";
1441 let serialized = serde_json::to_string(&string).unwrap();
1442 assert_eq!(serialized, "\"ABC\"");
1443 let deserialized: AsciiString = serde_json::from_str(&serialized).unwrap();
1444 assert_eq!(deserialized, string);
1445 }
1446
1447 #[cfg(feature = "serde")]
1448 #[test]
1449 fn test_serde_full_u8_range() {
1450 use crate::ascii_string::AsciiString;
1451 let mut string = AsciiString::with_capacity(256);
1452 for i in 0..=255 {
1453 string += i;
1454 }
1455 let serialized = serde_json::to_string(&string).unwrap();
1456 let deserialized: AsciiString = serde_json::from_str(&serialized).unwrap();
1457 assert_eq!(deserialized, string);
1458 }
1459}