dust_devil_core/
buffer_size.rs1use std::num::IntErrorKind;
4
5pub enum PrettyBufferSizeParseError {
7 Empty,
9
10 Zero,
12
13 InvalidFormat,
15
16 InvalidCharacters,
18
19 TooLarge,
21}
22
23pub fn parse_pretty_buffer_size(s: &str) -> Result<u32, PrettyBufferSizeParseError> {
35 let s = s.trim();
36
37 if s.is_empty() {
38 return Err(PrettyBufferSizeParseError::Empty);
39 }
40
41 let mut iter = s.chars();
42 let (s, radix) = match (iter.next(), iter.next().map(|c| c.to_ascii_lowercase())) {
43 (Some('0'), Some('x')) => (&s[2..], 16),
44 (Some('0'), Some('o')) => (&s[2..], 8),
45 (Some('0'), Some('b')) => (&s[2..], 2),
46 _ => (s, 10),
47 };
48
49 let mut iter = s.chars();
50 let (s, multiplier) = match iter.next_back().map(|c| c.to_ascii_lowercase()) {
51 Some('k') => (&s[..(s.len() - 1)], 1024),
52 Some('m') => (&s[..(s.len() - 1)], 1024 * 1024),
53 Some('g') => (&s[..(s.len() - 1)], 1024 * 1024 * 1024),
54 Some('b') => match iter.next_back().map(|c| c.to_ascii_lowercase()) {
55 Some('k') => (&s[..(s.len() - 2)], 1024),
56 Some('m') => (&s[..(s.len() - 2)], 1024 * 1024),
57 Some('g') => (&s[..(s.len() - 2)], 1024 * 1024 * 1024),
58 Some(_) if radix < 11 => (&s[..(s.len() - 1)], 1),
59 _ => (s, 1),
60 },
61 _ => (s, 1),
62 };
63
64 match s.chars().next() {
65 Some(c) if c.is_ascii_alphanumeric() => {}
66 _ => return Err(PrettyBufferSizeParseError::InvalidFormat),
67 }
68
69 let size = match u32::from_str_radix(s, radix) {
70 Ok(0) => return Err(PrettyBufferSizeParseError::Zero),
71 Ok(size) => size,
72 Err(parse_int_error) => {
73 return Err(match parse_int_error.kind() {
74 IntErrorKind::Empty => PrettyBufferSizeParseError::Empty,
75 IntErrorKind::PosOverflow => PrettyBufferSizeParseError::TooLarge,
76 _ => PrettyBufferSizeParseError::InvalidCharacters,
77 });
78 }
79 };
80
81 match size.checked_mul(multiplier) {
82 Some(size) => Ok(size),
83 None => Err(PrettyBufferSizeParseError::TooLarge),
84 }
85}