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}