padded_number_internal/
lib.rs

1//! # `padded-number-internal` - Internal crate whose items are then re-exported in `padded-number`
2
3/// Error originating from `PaddedNumber::try_new`
4#[derive(Debug, PartialEq, displaydoc::Display, thiserror::Error)]
5pub enum ParsePaddedNumberError {
6    /// "too few digits provided, expected at least '{0}', received '{1}'"
7    TooShort(u8, u8),
8    /// "too many digits provided, expected at most '{0}', received '{1}'"
9    TooLong(u8, u8),
10    /// "integer parse error, encountered non-ascii digit"
11    InvalidNumber(#[source] std::num::ParseIntError),
12}
13
14#[doc(hidden)]
15pub const fn parse(min: u8, max: u8, str: &str) -> Result<(u8, u64), ParsePaddedNumberError> {
16    {
17        let str_len = str.len();
18
19        if str_len == 0 && min == 0 {
20            return Ok((0, 0));
21        }
22
23        if str_len < min as usize {
24            return Err(ParsePaddedNumberError::TooShort(min, str_len as u8));
25        }
26
27        if str_len > max as usize {
28            return Err(ParsePaddedNumberError::TooLong(max, str_len as u8));
29        }
30    }
31
32    let leading_zeros = konst::iter::eval!(konst::string::chars(str), take_while(|char| *char == '0'), count()) as u8;
33
34    let remaining_number = konst::try_!(konst::result::map_err!(
35        u64::from_str_radix(str, 10),
36        ParsePaddedNumberError::InvalidNumber
37    ));
38
39    Ok((leading_zeros, remaining_number))
40}