1use crate::error::{ErrorKind, Result, err};
4
5pub fn parse_u64(digits: &[u8]) -> Result<u64> {
26 if digits.is_empty() {
27 return err(ErrorKind::Empty, 0);
28 }
29 let mut n: u64 = 0;
30 for (i, &b) in digits.iter().enumerate() {
31 if !b.is_ascii_digit() {
32 return err(ErrorKind::InvalidNumber, i);
33 }
34 n = match n
35 .checked_mul(10)
36 .and_then(|m| m.checked_add(u64::from(b - b'0')))
37 {
38 Some(v) => v,
39 None => return err(ErrorKind::NumberOverflow, i),
40 };
41 }
42 Ok(n)
43}
44
45pub(crate) const DELTA_SECONDS_MAX: u32 = 2_147_483_648;
47
48pub fn parse_u32_saturating(digits: &[u8]) -> Result<u32> {
65 if digits.is_empty() {
66 return err(ErrorKind::Empty, 0);
67 }
68 let mut n: u32 = 0;
69 for (i, &b) in digits.iter().enumerate() {
70 if !b.is_ascii_digit() {
71 return err(ErrorKind::InvalidNumber, i);
72 }
73 n = n
74 .saturating_mul(10)
75 .saturating_add(u32::from(b - b'0'))
76 .min(DELTA_SECONDS_MAX);
77 }
78 Ok(n)
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_parse_u64_rejects_signs_and_overflow() {
87 assert_eq!(parse_u64(b"0"), Ok(0));
88 assert_eq!(parse_u64(b"007"), Ok(7));
89 assert_eq!(parse_u64(b"18446744073709551615"), Ok(u64::MAX));
90 let e = parse_u64(b"18446744073709551616").unwrap_err();
91 assert_eq!((e.kind(), e.offset()), (ErrorKind::NumberOverflow, 19));
92 assert_eq!(
93 parse_u64(b"+1").unwrap_err().kind(),
94 ErrorKind::InvalidNumber
95 );
96 assert_eq!(
97 parse_u64(b"-1").unwrap_err().kind(),
98 ErrorKind::InvalidNumber
99 );
100 assert_eq!(parse_u64(b"").unwrap_err().kind(), ErrorKind::Empty);
101 let e = parse_u64(b"1 ").unwrap_err();
102 assert_eq!((e.kind(), e.offset()), (ErrorKind::InvalidNumber, 1));
103 }
104
105 #[test]
106 fn test_parse_u32_saturating_boundaries() {
107 assert_eq!(parse_u32_saturating(b"2147483647"), Ok(2_147_483_647));
108 assert_eq!(parse_u32_saturating(b"2147483648"), Ok(2_147_483_648));
109 assert_eq!(parse_u32_saturating(b"2147483649"), Ok(2_147_483_648));
110 assert_eq!(parse_u32_saturating(b"4294967296"), Ok(2_147_483_648));
111 assert_eq!(
112 parse_u32_saturating(b"").unwrap_err().kind(),
113 ErrorKind::Empty
114 );
115 assert_eq!(
116 parse_u32_saturating(b"6s").unwrap_err().kind(),
117 ErrorKind::InvalidNumber
118 );
119 }
120}