Move hex number processing into own function

This commit is contained in:
merkrafter authored and David Peter committed 2021-11-14 09:26:21 +01:00
1 parent 55d02c933a
commit 1b33e516d9
1 file changed
+43 -24
+43 -24
View File
@@ -147,14 +147,11 @@ fn run() -> Result<(), AnyhowError> {
let block_size = matches let block_size = matches
.value_of("block_size") .value_of("block_size")
.map(|bs| { .map(|bs| {
if bs.starts_with(HEX_PREFIX) { if let Some(hex_number) = try_parse_as_hex_number(bs) {
let n = &bs[HEX_PREFIX.len()..]; return hex_number.map_err(|e| anyhow!(e)).and_then(|x| {
return i64::from_str_radix(n, 16) PositiveI64::new(x)
.map_err(|_| anyhow!("could not parse block size argument as hex number")) .ok_or_else(|| anyhow!("block size argument must be positive"))
.and_then(|x| { });
PositiveI64::new(x)
.ok_or_else(|| anyhow!("block size argument must be positive"))
});
} }
let (num, unit) = extract_num_and_unit_from(bs)?; let (num, unit) = extract_num_and_unit_from(bs)?;
if let Unit::Block { custom_size: _ } = unit { if let Unit::Block { custom_size: _ } = unit {
@@ -446,22 +443,8 @@ fn parse_byte_offset(n: &str, block_size: PositiveI64) -> Result<ByteOffset, Byt
}) })
}; };
if n.starts_with(HEX_PREFIX) { if let Some(hex_number) = try_parse_as_hex_number(n) {
let n = &n[HEX_PREFIX.len()..]; return hex_number.map(into_byte_offset)?;
let mut chars = n.chars();
match chars.next() {
Some(c @ '+') | Some(c @ '-') => {
return if chars.next().is_none() {
Err(EmptyAfterSign)
} else {
Err(SignFoundAfterHexPrefix(c))
}
}
_ => (),
}
return i64::from_str_radix(n, 16)
.map(into_byte_offset)
.map_err(ParseNum)?;
} }
let (num, mut unit) = extract_num_and_unit_from(n)?; let (num, mut unit) = extract_num_and_unit_from(n)?;
@@ -551,6 +534,26 @@ fn process_sign_of(n: &str) -> Result<(&str, ByteOffsetKind), ByteOffsetParseErr
} }
} }
/// If `n` starts with a hex prefix, its remaining part is returned as some number (if possible),
/// otherwise None is returned.
fn try_parse_as_hex_number(n: &str) -> Option<Result<i64, ByteOffsetParseError>> {
use ByteOffsetParseError::*;
n.strip_prefix(HEX_PREFIX).map(|num| {
let mut chars = num.chars();
match chars.next() {
Some(c @ '+') | Some(c @ '-') => {
return if chars.next().is_none() {
Err(EmptyAfterSign)
} else {
Err(SignFoundAfterHexPrefix(c))
}
}
_ => (),
}
i64::from_str_radix(num, 16).map_err(ParseNum)
})
}
#[test] #[test]
fn unit_multipliers() { fn unit_multipliers() {
use Unit::*; use Unit::*;
@@ -577,6 +580,22 @@ fn test_process_sign() {
assert_eq!(process_sign_of(""), Err(Empty)); assert_eq!(process_sign_of(""), Err(Empty));
} }
#[test]
fn test_parse_as_hex() {
assert_eq!(try_parse_as_hex_number("73"), None);
assert_eq!(try_parse_as_hex_number("0x1337"), Some(Ok(0x1337)));
assert!(if let Some(Err(_)) = try_parse_as_hex_number("0xnope") {
true
} else {
false
});
assert!(if let Some(Err(_)) = try_parse_as_hex_number("0x-1") {
true
} else {
false
});
}
#[test] #[test]
fn extract_num_and_unit() { fn extract_num_and_unit() {
use ByteOffsetParseError::*; use ByteOffsetParseError::*;