brainfoamkit_lib/
ascii_char.rs

1// SPDX-FileCopyrightText: 2023 - 2024 Ali Sajid Imami
2//
3// SPDX-License-Identifier: Apache-2.0
4// SPDX-License-Identifier: MIT
5
6use crate::Byte;
7
8/// A struct representing an ASCII character.
9///
10/// This struct is used to represent an ASCII character in terms of a
11/// [`Byte`](struct.Byte.html) value. This struct allows for interrogating the
12/// character in terms of its binary, decimal, and hexadecimal values, as well
13/// as its character code, character description, and character value.
14///
15/// # Examples
16///
17/// ```
18/// use brainfoamkit_lib::{
19///     AsciiChar,
20///     Byte,
21/// };
22///
23/// let ascii_char: AsciiChar =
24///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
25///
26/// assert_eq!(ascii_char.binary_value(), Byte::from(97));
27/// assert_eq!(ascii_char.decimal_value(), 97);
28/// assert_eq!(ascii_char.hexadecimal_value(), "0x61");
29/// assert_eq!(ascii_char.character_code(), "LCA");
30/// assert_eq!(ascii_char.character_description(), "Lowercase letter a");
31/// assert_eq!(ascii_char.character_value(), "a");
32/// ```
33///
34/// # ASCII Character Types
35///
36/// The following ASCII character types are available:
37///
38/// * Control characters
39/// * Printable characters
40///     * Whitespace characters
41///     * Digit characters
42///     * Letter characters
43///         * Uppercase characters
44///         * Lowercase characters
45///     * Symbol characters
46///
47/// # ASCII Character Type Examples
48///
49/// ## Control Characters
50///
51/// ```
52/// use brainfoamkit_lib::{
53///     AsciiChar,
54///     Byte,
55/// };
56///
57/// let ascii_char: AsciiChar =
58///     AsciiChar::new(Byte::from(0), "NUL", "Null character", "\0");
59///
60/// assert_eq!(ascii_char.is_control(), true);
61/// ```
62///
63/// ## Printable Characters
64///
65/// ```
66/// use brainfoamkit_lib::{
67///     AsciiChar,
68///     Byte,
69/// };
70///
71/// let ascii_char: AsciiChar =
72///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
73///
74/// assert_eq!(ascii_char.is_printable(), true);
75/// ```
76///
77/// ## Whitespace Characters
78///
79/// ```
80/// use brainfoamkit_lib::{
81///     AsciiChar,
82///     Byte,
83/// };
84///
85/// let ascii_char: AsciiChar =
86///     AsciiChar::new(Byte::from(9), "CTAB", "Horizontal tab", "\t");
87///
88/// assert_eq!(ascii_char.is_whitespace(), true);
89/// ```
90///
91/// ## Digit Characters
92///
93/// ```
94/// use brainfoamkit_lib::{
95///     AsciiChar,
96///     Byte,
97/// };
98///
99/// let ascii_char: AsciiChar =
100///     AsciiChar::new(Byte::from(49), "DIG1", "Digit one", "1");
101///
102/// assert_eq!(ascii_char.is_digit(), true);
103/// ```
104///
105/// ## Letter Characters
106///
107/// ### Uppercase Characters
108///
109/// ```
110/// use brainfoamkit_lib::{
111///     AsciiChar,
112///     Byte,
113/// };
114///
115/// let ascii_char: AsciiChar =
116///     AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
117///
118/// assert_eq!(ascii_char.is_uppercase(), true);
119/// assert_eq!(ascii_char.is_lowercase(), false);
120/// assert_eq!(ascii_char.is_letter(), true);
121/// ```
122///
123/// ### Lowercase Characters
124///
125/// ```
126/// use brainfoamkit_lib::{
127///     AsciiChar,
128///     Byte,
129/// };
130///
131/// let ascii_char: AsciiChar =
132///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
133///
134/// assert_eq!(ascii_char.is_lowercase(), true);
135/// assert_eq!(ascii_char.is_uppercase(), false);
136/// assert_eq!(ascii_char.is_letter(), true);
137/// ```
138///
139/// ## Symbol Characters
140///
141/// ```
142/// use brainfoamkit_lib::{
143///     AsciiChar,
144///     Byte,
145/// };
146///
147/// let ascii_char: AsciiChar =
148///     AsciiChar::new(Byte::from(64), "AT", "At Symbol", "@");
149///
150/// assert_eq!(ascii_char.is_symbol(), true);
151/// ```
152///
153/// # References
154///
155/// * [ASCII](https://en.wikipedia.org/wiki/ASCII)
156/// * [ASCII Table](https://www.asciitable.com/)
157/// * [ASCII Table and Description](https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html)
158#[derive(Clone, Debug, Eq, PartialEq)]
159pub struct AsciiChar {
160    binary_value:          Byte,
161    character_code:        String,
162    character_description: String,
163    character_value:       String,
164}
165
166impl AsciiChar {
167    /// Create a new `AsciiChar` instance.
168    ///
169    /// This function creates a new `AsciiChar` instance from the given
170    /// [`Byte`](struct.Byte.html) value, character code, character
171    /// description, and character value.
172    ///
173    /// # Examples
174    ///
175    /// ```
176    /// use brainfoamkit_lib::{
177    ///     AsciiChar,
178    ///     Byte,
179    /// };
180    ///
181    /// let ascii_char: AsciiChar =
182    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
183    ///
184    /// assert_eq!(ascii_char.binary_value(), Byte::from(97));
185    /// assert_eq!(ascii_char.decimal_value(), 97);
186    /// assert_eq!(ascii_char.hexadecimal_value(), "0x61");
187    /// assert_eq!(ascii_char.character_code(), "LCA");
188    /// assert_eq!(ascii_char.character_description(), "Lowercase letter a");
189    /// ```
190    #[must_use]
191    pub fn new(
192        byte: Byte,
193        character_code: &str,
194        character_description: &str,
195        character_value: &str,
196    ) -> Self {
197        let binary_value: Byte = byte;
198        let character_code: String = character_code.to_string().to_uppercase();
199        let character_description: String = character_description.to_string();
200        let character_value: String = character_value.to_string();
201
202        Self {
203            binary_value,
204            character_code,
205            character_description,
206            character_value,
207        }
208    }
209
210    /// Returns `true` if the `AsciiChar` instance is a control character.
211    ///
212    /// # Examples
213    ///
214    /// ```
215    /// use brainfoamkit_lib::{
216    ///     AsciiChar,
217    ///     Byte,
218    /// };
219    ///
220    /// let ascii_char: AsciiChar =
221    ///     AsciiChar::new(Byte::from(0), "NUL", "Null character", "\0");
222    ///
223    /// assert_eq!(ascii_char.is_control(), true);
224    /// ```
225    ///
226    /// ## Control Characters
227    ///
228    /// * NUL (Null character)
229    /// * SOH (Start of heading)
230    /// * STX (Start of text)
231    /// * ETX (End of text)
232    /// * EOT (End of transmission)
233    /// * ENQ (Enquiry)
234    /// * ACK (Acknowledgement)
235    /// * BEL (Bell)
236    /// * BS (Backspace)
237    /// * HT (Horizontal tab)
238    /// * LF (Line feed)
239    /// * VT (Vertical tab)
240    /// * FF (Form feed)
241    /// * CR (Carriage return)
242    /// * SO (Shift out)
243    /// * SI (Shift in)
244    /// * DLE (Data link escape)
245    /// * DC1 (Device control 1)
246    /// * DC2 (Device control 2)
247    /// * DC3 (Device control 3)
248    /// * DC4 (Device control 4)
249    /// * NAK (Negative acknowledgement)
250    /// * SYN (Synchronous idle)
251    /// * ETB (End of transmission block)
252    /// * CAN (Cancel)
253    /// * EM (End of medium)
254    /// * SUB (Substitute)
255    /// * ESC (Escape)
256    /// * FS (File separator)
257    /// * GS (Group separator)
258    /// * RS (Record separator)
259    /// * US (Unit separator)
260    /// * DEL (Delete)
261    ///
262    /// # References
263    ///
264    /// * [ASCII Control Characters](https://en.wikipedia.org/wiki/ASCII#Control_characters)
265    #[must_use]
266    pub fn is_control(&self) -> bool {
267        self.decimal_value() < 32 || self.decimal_value() == 127
268    }
269
270    /// Returns `true` if the `AsciiChar` instance is a printable character.
271    ///
272    /// # Examples
273    ///
274    /// ```
275    /// use brainfoamkit_lib::{
276    ///     AsciiChar,
277    ///     Byte,
278    /// };
279    ///
280    /// let lca: AsciiChar =
281    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
282    /// let uca: AsciiChar =
283    ///     AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
284    /// let symat: AsciiChar =
285    ///     AsciiChar::new(Byte::from(64), "SYMAT", "Symbol At", "@");
286    /// let dig1: AsciiChar =
287    ///     AsciiChar::new(Byte::from(49), "DIG1", "Digit one", "1");
288    /// let sp: AsciiChar = AsciiChar::new(Byte::from(32), "SP", "Space", " ");
289    ///
290    /// assert_eq!(lca.is_printable(), true);
291    /// assert_eq!(uca.is_printable(), true);
292    /// assert_eq!(symat.is_printable(), true);
293    /// assert_eq!(dig1.is_printable(), true);
294    /// assert_eq!(sp.is_printable(), true);
295    /// ```
296    ///
297    /// ## Printable Characters
298    ///
299    /// * [All uppercase letters](#methods.is_uppercase)
300    /// * [All lowercase letters](#methods.is_lowercase)
301    /// * [All digit characters](#methods.is_digit)
302    /// * [All symbol characters](#methods.is_symbol)
303    /// * [All whitespace characters](#methods.is_whitespace)
304    ///
305    /// # References
306    ///
307    /// * [ASCII Printable Characters](https://en.wikipedia.org/wiki/ASCII#Printable_characters)
308    #[must_use]
309    pub fn is_printable(&self) -> bool {
310        self.decimal_value() > 31 && self.decimal_value() < 127
311    }
312
313    /// Returns `true` if the `AsciiChar` instance is a whitespace character.
314    ///
315    /// # Examples
316    ///
317    /// ```
318    /// use brainfoamkit_lib::{
319    ///     AsciiChar,
320    ///     Byte,
321    /// };
322    ///
323    /// let ascii_char: AsciiChar =
324    ///     AsciiChar::new(Byte::from(9), "CTAB", "Horizontal tab", "\t");
325    ///
326    /// assert_eq!(ascii_char.is_whitespace(), true);
327    /// ```
328    ///
329    /// ## Whitespace Characters
330    ///
331    /// * SP (Space)
332    /// * HT (Horizontal tab)
333    /// * LF (Line feed)
334    /// * VT (Vertical tab)
335    /// * FF (Form feed)
336    /// * CR (Carriage return)
337    ///
338    /// # References
339    ///
340    /// * [ASCII Whitespace Characters](https://en.wikipedia.org/wiki/Whitespace_character)
341    #[must_use]
342    pub fn is_whitespace(&self) -> bool {
343        self.decimal_value() == 9
344            || self.decimal_value() == 10
345            || self.decimal_value() == 11
346            || self.decimal_value() == 12
347            || self.decimal_value() == 13
348            || self.decimal_value() == 32
349    }
350
351    /// Returns `true` if the `AsciiChar` instance is a digit character.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// use brainfoamkit_lib::{
357    ///     AsciiChar,
358    ///     Byte,
359    /// };
360    ///
361    /// let ascii_char: AsciiChar =
362    ///     AsciiChar::new(Byte::from(49), "DIG1", "Digit one", "1");
363    ///
364    /// assert_eq!(ascii_char.is_digit(), true);
365    /// ```
366    ///
367    /// ## Digit Characters
368    ///
369    /// * All digit characters from 0 to 9
370    ///
371    /// # References
372    ///
373    /// * [ASCII Digit Characters](https://en.wikipedia.org/wiki/ASCII)
374    #[must_use]
375    pub fn is_digit(&self) -> bool {
376        self.decimal_value() > 47 && self.decimal_value() < 58
377    }
378
379    /// Returns `true` if the `AsciiChar` instance is a letter character.
380    ///
381    /// # Examples
382    ///
383    /// ## Lowercase Letters
384    ///
385    /// ```
386    /// use brainfoamkit_lib::{
387    ///     AsciiChar,
388    ///     Byte,
389    /// };
390    ///
391    /// let ascii_char: AsciiChar =
392    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
393    ///
394    /// assert_eq!(ascii_char.is_letter(), true);
395    /// ```
396    ///
397    /// ## Uppercase Letters
398    ///
399    /// ```
400    /// use brainfoamkit_lib::{
401    ///     AsciiChar,
402    ///     Byte,
403    /// };
404    ///
405    /// let lca: AsciiChar =
406    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
407    /// let uca: AsciiChar =
408    ///     AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
409    ///
410    /// assert_eq!(lca.is_letter(), true);
411    /// assert_eq!(uca.is_letter(), true);
412    /// ```
413    ///
414    /// ## Letter Characters
415    ///
416    /// * [All uppercase letters](#methods.is_uppercase)
417    /// * [All lowercase letters](#methods.is_lowercase)
418    ///
419    /// # References
420    ///
421    /// * [ASCII Letter Characters](https://en.wikipedia.org/wiki/ASCII)
422    #[must_use]
423    pub fn is_letter(&self) -> bool {
424        self.is_lowercase() || self.is_uppercase()
425    }
426
427    /// Returns `true` if the `AsciiChar` instance is an uppercase letter
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// use brainfoamkit_lib::{
433    ///     AsciiChar,
434    ///     Byte,
435    /// };
436    ///
437    /// let ascii_char: AsciiChar =
438    ///     AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter A", "A");
439    ///
440    /// assert_eq!(ascii_char.is_uppercase(), true);
441    /// ```
442    ///
443    /// ## Uppercase Letters
444    ///
445    /// * All uppercase letters from A to Z
446    ///
447    /// # References
448    ///
449    /// * [ASCII Uppercase Characters](https://en.wikipedia.org/wiki/ASCII)
450    #[must_use]
451    pub fn is_uppercase(&self) -> bool {
452        self.decimal_value() > 64 && self.decimal_value() < 91
453    }
454
455    /// Returns `true` if the `AsciiChar` instance is a lowercase letter
456    ///
457    /// # Examples
458    ///
459    /// ```
460    /// use brainfoamkit_lib::{
461    ///     AsciiChar,
462    ///     Byte,
463    /// };
464    ///
465    /// let ascii_char: AsciiChar =
466    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
467    ///
468    /// assert_eq!(ascii_char.is_lowercase(), true);
469    /// ```
470    ///
471    /// ## Lowercase Letters
472    ///
473    /// * All lowercase letters from a to z
474    ///
475    /// # References
476    ///
477    /// * [ASCII Lowercase Characters](https://en.wikipedia.org/wiki/ASCII)
478    #[must_use]
479    pub fn is_lowercase(&self) -> bool {
480        self.decimal_value() > 96 && self.decimal_value() < 123
481    }
482
483    /// Returns `true` if the `AsciiChar` instance is a symbol character.
484    ///
485    /// # Examples
486    ///
487    /// ```
488    /// use brainfoamkit_lib::{
489    ///     AsciiChar,
490    ///     Byte,
491    /// };
492    ///
493    /// let ascii_char: AsciiChar =
494    ///     AsciiChar::new(Byte::from(64), "SYMAT", "Symbol at", "@");
495    ///
496    /// assert_eq!(ascii_char.is_symbol(), true);
497    /// ```
498    ///
499    /// ## Symbol Characters
500    ///
501    /// * All symbol characters from ! to /
502    /// * All symbol characters from : to @
503    /// * All symbol characters from [ to `
504    /// * All symbol characters from { to ~
505    ///
506    /// # References
507    ///
508    /// * [ASCII Symbol Characters](https://en.wikipedia.org/wiki/ASCII)
509    #[must_use]
510    #[allow(clippy::doc_markdown)]
511    pub fn is_symbol(&self) -> bool {
512        self.decimal_value() > 32 && self.decimal_value() < 48
513            || self.decimal_value() > 57 && self.decimal_value() < 65
514            || self.decimal_value() > 90 && self.decimal_value() < 97
515            || self.decimal_value() > 122 && self.decimal_value() < 127
516    }
517
518    /// Returns the `AsciiChar` instance's binary value.
519    ///
520    /// This function returns the `AsciiChar` instance's binary value as a
521    /// [`Byte`](struct.Byte.html).
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// use brainfoamkit_lib::{
527    ///     AsciiChar,
528    ///     Byte,
529    /// };
530    ///
531    /// let ascii_char: AsciiChar =
532    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
533    ///
534    /// assert_eq!(ascii_char.binary_value(), Byte::from(97));
535    /// ```
536    #[must_use]
537    pub const fn binary_value(&self) -> Byte {
538        self.binary_value
539    }
540
541    /// Returns the `AsciiChar` instance's decimal value.
542    ///
543    /// This function returns the `AsciiChar` instance's decimal value as a
544    /// `u8`.
545    ///
546    /// # Examples
547    ///
548    /// ```
549    /// use brainfoamkit_lib::{
550    ///     AsciiChar,
551    ///     Byte,
552    /// };
553    ///
554    /// let ascii_char: AsciiChar =
555    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
556    ///
557    /// assert_eq!(ascii_char.decimal_value(), 97);
558    /// ```
559    #[must_use]
560    pub fn decimal_value(&self) -> u8 {
561        u8::from(&self.binary_value)
562    }
563
564    /// Returns the `AsciiChar` instance's hexadecimal value.
565    ///
566    /// This function returns the `AsciiChar` instance's hexadecimal value as a
567    /// `String`.
568    ///
569    /// # Examples
570    ///
571    /// ```
572    /// use brainfoamkit_lib::{
573    ///     AsciiChar,
574    ///     Byte,
575    /// };
576    ///
577    /// let ascii_char: AsciiChar =
578    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
579    ///
580    /// assert_eq!(ascii_char.hexadecimal_value(), "0x61");
581    /// ```
582    #[must_use]
583    pub fn hexadecimal_value(&self) -> String {
584        format!("{:#04X}", self.decimal_value())
585    }
586
587    /// Returns the `AsciiChar` instance's character code.
588    ///
589    /// This function returns the `AsciiChar` instance's character code as a
590    /// `String`.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use brainfoamkit_lib::{
596    ///     AsciiChar,
597    ///     Byte,
598    /// };
599    ///
600    /// let ascii_char: AsciiChar =
601    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
602    ///
603    /// assert_eq!(ascii_char.character_code(), "LCA");
604    /// ```
605    #[must_use]
606    pub fn character_code(&self) -> String {
607        self.character_code.clone()
608    }
609
610    /// Returns the `AsciiChar` instance's character description.
611    ///
612    /// This function returns the `AsciiChar` instance's character description
613    /// as a `String`.
614    ///
615    /// # Examples
616    ///
617    /// ```
618    /// use brainfoamkit_lib::{
619    ///     AsciiChar,
620    ///     Byte,
621    /// };
622    ///
623    /// let ascii_char: AsciiChar =
624    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
625    ///
626    /// assert_eq!(ascii_char.character_description(), "Lowercase letter a");
627    /// ```
628    #[must_use]
629    pub fn character_description(&self) -> String {
630        self.character_description.clone()
631    }
632
633    /// Returns the `AsciiChar` instance's character value.
634    ///
635    /// This function returns the `AsciiChar` instance's character value as a
636    /// `String`.
637    ///
638    /// # Examples
639    ///
640    /// ```
641    /// use brainfoamkit_lib::{
642    ///     AsciiChar,
643    ///     Byte,
644    /// };
645    ///
646    /// let ascii_char: AsciiChar =
647    ///     AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
648    ///
649    /// assert_eq!(ascii_char.character_value(), "a");
650    /// ```
651    #[must_use]
652    pub fn character_value(&self) -> String {
653        self.character_value.clone()
654    }
655}
656
657#[cfg(test)]
658mod tests {
659    use super::*;
660
661    #[test]
662    fn test_ascii_char() {
663        let ascii_char: AsciiChar =
664            AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
665
666        assert_eq!(ascii_char.binary_value(), Byte::from(97));
667        assert_eq!(ascii_char.decimal_value(), 97);
668        assert_eq!(ascii_char.hexadecimal_value(), "0x61");
669        assert_eq!(ascii_char.character_code(), "LCA");
670        assert_eq!(ascii_char.character_description(), "Lowercase letter a");
671        assert_eq!(ascii_char.character_value(), "a");
672    }
673
674    #[test]
675    fn test_ascii_char_is_control() {
676        let ascii_char: AsciiChar = AsciiChar::new(Byte::from(0), "NUL", "Null character", "\0");
677
678        assert!(ascii_char.is_control());
679    }
680
681    #[test]
682    fn test_ascii_char_is_printable() {
683        let lca: AsciiChar = AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
684        let uca: AsciiChar = AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
685        let symat: AsciiChar = AsciiChar::new(Byte::from(64), "SYMAT", "Symbol At", "@");
686        let dig1: AsciiChar = AsciiChar::new(Byte::from(49), "DIG1", "Digit one", "1");
687        let sp: AsciiChar = AsciiChar::new(Byte::from(32), "SP", "Space", " ");
688
689        assert!(lca.is_printable());
690        assert!(uca.is_printable());
691        assert!(symat.is_printable());
692        assert!(dig1.is_printable());
693        assert!(sp.is_printable());
694    }
695
696    #[test]
697    fn test_ascii_char_is_letter() {
698        let lca: AsciiChar = AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
699        let uca: AsciiChar = AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
700
701        assert!(lca.is_letter());
702        assert!(uca.is_letter());
703    }
704
705    #[test]
706    fn test_ascii_char_is_uppercase() {
707        let ascii_char: AsciiChar =
708            AsciiChar::new(Byte::from(65), "UCA", "Uppercase letter a", "A");
709
710        assert!(ascii_char.is_uppercase());
711        assert!(!ascii_char.is_lowercase());
712        assert!(ascii_char.is_letter());
713    }
714
715    #[test]
716    fn test_ascii_char_is_lowercase() {
717        let ascii_char: AsciiChar =
718            AsciiChar::new(Byte::from(97), "LCA", "Lowercase letter a", "a");
719
720        assert!(ascii_char.is_lowercase());
721        assert!(!ascii_char.is_uppercase());
722        assert!(ascii_char.is_letter());
723    }
724
725    #[test]
726    fn test_ascii_char_is_whitespace() {
727        let whitespace_chars = vec![9, 10, 11, 12, 13, 32];
728        for &val in &whitespace_chars {
729            let ascii_char = AsciiChar::new(Byte::from(val), "", "", "");
730            assert!(
731                ascii_char.is_whitespace(),
732                "Character with decimal value {} should be identified as whitespace",
733                val
734            );
735        }
736
737        let non_whitespace_char = AsciiChar::new(Byte::from(65), "", "", "");
738        assert!(
739            !non_whitespace_char.is_whitespace(),
740            "Character with decimal value 65 should not be identified as whitespace"
741        );
742    }
743
744    #[test]
745    fn test_ascii_char_is_digit() {
746        let digit_chars = vec![48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
747        for &val in &digit_chars {
748            let ascii_char = AsciiChar::new(Byte::from(val), "", "", "");
749            assert!(
750                ascii_char.is_digit(),
751                "Character with decimal value {} should be identified as a digit",
752                val
753            );
754        }
755
756        let non_digit_char = AsciiChar::new(Byte::from(65), "", "", "");
757        assert!(
758            !non_digit_char.is_digit(),
759            "Character with decimal value 65 should not be identified as a digit"
760        );
761    }
762
763    #[test]
764    fn test_ascii_char_is_symbol() {
765        let symbol_chars = vec![
766            33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64,
767            91, 92, 93, 94, 95, 96, 123, 124, 125, 126,
768        ];
769        for &val in &symbol_chars {
770            let ascii_char = AsciiChar::new(Byte::from(val), "", "", "");
771            assert!(
772                ascii_char.is_symbol(),
773                "Character with decimal value {} should be identified as a symbol",
774                val
775            );
776        }
777
778        let non_symbol_char = AsciiChar::new(Byte::from(65), "", "", "");
779        assert!(
780            !non_symbol_char.is_symbol(),
781            "Character with decimal value 65 should not be identified as a symbol"
782        );
783    }
784
785    #[test]
786    fn test_ascii_char_binary_value() {
787        let ascii_char = AsciiChar::new(Byte::from(97), "", "", "");
788        assert_eq!(
789            ascii_char.binary_value(),
790            Byte::from(97),
791            "Binary value should be equal to the input value"
792        );
793    }
794}