digit_sequence/
strings.rs

1use crate::{CrateError, CrateResult, DigitSequence};
2use std::{fmt::Display, str::FromStr};
3
4/// The string representation of a [DigitSequence] is just the concatenation of its digits.
5///
6/// ```
7/// use digit_sequence::*;
8///
9/// let digit_sequence: DigitSequence = DigitSequence::new();
10/// assert_eq!(digit_sequence.to_string(), "");
11///
12/// let digit_sequence: DigitSequence = 9u8.into();
13/// assert_eq!(digit_sequence.to_string(), "9");
14///
15/// let digit_sequence: DigitSequence = 175438u32.into();
16/// assert_eq!(digit_sequence.to_string(), "175438");
17/// ```
18impl Display for DigitSequence {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        for &digit in &self.0 {
21            write!(f, "{}", digit)?;
22        }
23
24        Ok(())
25    }
26}
27
28/// Parsing a &[str] or [String] works if it only consists of base-10 digits,
29/// with the exception of the empty string:
30///
31/// ```
32/// use digit_sequence::*;
33///
34/// # fn main() -> GenericResult<()> {
35///
36/// let sequence: DigitSequence = "".parse()?;
37/// assert_eq!(sequence, []);
38///
39/// let sequence: DigitSequence = "2".parse()?;
40/// assert_eq!(sequence, [2]);
41///
42/// let sequence: DigitSequence = "0302".parse()?;
43/// assert_eq!(sequence, [0, 3, 0, 2]);
44///
45/// let sequence: DigitSequence = String::from("0302").parse()?;
46/// assert_eq!(sequence, [0, 3, 0, 2]);
47///
48/// # Ok(())
49/// # }
50/// ```
51///
52/// Any other string pattern results in a [CrateError::NonDigitChar]:
53///
54/// ```
55/// use digit_sequence::*;
56///
57/// # fn main() -> GenericResult<()> {
58///
59/// let result: CrateResult<DigitSequence> = "<NOT A NUMBER>".parse();
60/// assert!(result == Err(CrateError::NonDigitChar('<')));
61///
62/// let result: CrateResult<DigitSequence> = "90xy".parse();
63/// assert!(result == Err(CrateError::NonDigitChar('x')));
64///
65/// let result: CrateResult<DigitSequence> = "-90".parse();
66/// assert!(result == Err(CrateError::NonDigitChar('-')));
67///
68/// let result: CrateResult<DigitSequence> = " 90".parse();
69/// assert!(result == Err(CrateError::NonDigitChar(' ')));
70///  
71/// # Ok(())
72/// # }
73/// ```
74impl FromStr for DigitSequence {
75    type Err = CrateError;
76
77    fn from_str(s: &str) -> CrateResult<Self> {
78        let mut digits: Vec<u8> = Vec::new();
79
80        for current_char in s.chars() {
81            match current_char.to_digit(10) {
82                Some(digit) => digits.push(digit as u8),
83                None => return Err(CrateError::NonDigitChar(current_char)),
84            }
85        }
86
87        Ok(DigitSequence(digits))
88    }
89}