pub const MAX_INT_DIGITS: usize = 11;
pub fn write_int(buffer: &mut [u8], mut value: i32) -> &mut [u8] {
debug_assert!(buffer.len() >= MAX_INT_DIGITS);
let mut buffer_index = 0;
let is_negative = value.is_negative();
if !is_negative {
value = -value;
}
if value == 0 {
buffer[buffer_index] = b'0';
buffer_index += 1;
}
while value != 0 {
buffer[buffer_index] = b'0' + -(value % 10) as u8;
buffer_index += 1;
value /= 10;
}
if is_negative {
buffer[buffer_index] = b'-';
buffer_index += 1;
}
buffer[0..buffer_index].reverse();
&mut buffer[0..buffer_index]
}
pub fn parse_int(mut buffer: &[u8]) -> Option<i32> {
if buffer.is_empty() || buffer.len() > MAX_INT_DIGITS {
return None;
}
let is_negative = buffer[0] == b'-';
if is_negative {
buffer = &buffer[1..];
}
let mut value = 0;
for char in buffer.iter() {
if *char < b'0' || *char > b'9' {
return None;
} else {
value *= 10;
value -= (*char - b'0') as i32;
}
}
if is_negative {
Some(value)
} else {
Some(-value)
}
}
const HEX_BYTE_SIZE: usize = 2;
fn get_ascii(byte: u8) -> u8 {
debug_assert!(byte <= 15, "The provided byte must be in range [0, 15]");
match byte {
0..=9 => b'0' + byte,
10..=15 => b'a' + byte - 10,
_ => unreachable!(),
}
}
pub fn parse_byte_to_hex(byte: u8) -> [u8; HEX_BYTE_SIZE] {
let top = byte >> 4;
let bottom = byte & 0x0f;
[get_ascii(top), get_ascii(bottom)]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_write_int() {
let mut buffer = [0; 128];
assert_eq!(write_int(&mut buffer, 0), b"0");
assert_eq!(write_int(&mut buffer, -1), b"-1");
assert_eq!(write_int(&mut buffer, 1), b"1");
assert_eq!(write_int(&mut buffer, -42), b"-42");
assert_eq!(write_int(&mut buffer, 42), b"42");
assert_eq!(write_int(&mut buffer, -2147483648), b"-2147483648");
assert_eq!(write_int(&mut buffer, 2147483647), b"2147483647");
}
#[test]
fn test_parse_int() {
assert_eq!(parse_int(b"0"), Some(0));
assert_eq!(parse_int(b"-1"), Some(-1));
assert_eq!(parse_int(b"1"), Some(1));
assert_eq!(parse_int(b"-42"), Some(-42));
assert_eq!(parse_int(b"42"), Some(42));
assert_eq!(parse_int(b"-2147483648"), Some(-2147483648));
assert_eq!(parse_int(b"2147483647"), Some(2147483647));
assert_eq!(parse_int(b""), None);
assert_eq!(parse_int(b"abc"), None);
assert_eq!(parse_int(b"-b"), None);
assert_eq!(parse_int(b"123456a"), None);
assert_eq!(parse_int(b"z12354"), None);
}
#[test]
fn test_byte_to_hex() {
let expecting: Vec<u8> = (b'0'..=b'9').chain(b'a'..=b'f').collect();
for i in 0..15 {
let ascii_value = get_ascii(i);
let expected = expecting[i as usize];
assert_eq!(ascii_value, expected)
}
}
#[test]
#[should_panic]
fn test_byte_to_hex_invalid() {
get_ascii(0x97);
}
#[test]
fn test_parse_byte_to_hex() {
for i in 0u8..=255u8 {
let expecting = format!("{:02x}", i);
let got = parse_byte_to_hex(i);
assert_eq!(expecting.as_bytes(), got);
}
}
}