argument: move out parse_hex_or_decimal.

There's some common code.

BUG=None
TEST=build

Change-Id: I3845acfa9dc6370ef4f8e9eb1ef3a67b339aa7f3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3524361
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Junichi Uekawa <uekawa@chromium.org>
This commit is contained in:
Junichi Uekawa 2022-03-15 11:32:24 +09:00 committed by Commit Bot
parent e55b79102c
commit a4a1669896
2 changed files with 26 additions and 17 deletions

View file

@ -395,6 +395,21 @@ pub fn print_help(program_name: &str, required_arg: &str, args: &[Argument]) {
}
}
pub fn parse_hex_or_decimal(maybe_hex_string: &str) -> Result<u64> {
// Parse string starting with 0x as hex and others as numbers.
if let Some(hex_string) = maybe_hex_string.strip_prefix("0x") {
u64::from_str_radix(hex_string, 16)
} else if let Some(hex_string) = maybe_hex_string.strip_prefix("0X") {
u64::from_str_radix(hex_string, 16)
} else {
u64::from_str(maybe_hex_string)
}
.map_err(|e| Error::InvalidValue {
value: maybe_hex_string.to_string(),
expected: e.to_string(),
})
}
pub struct KeyValuePair<'a> {
context: &'a str,
key: &'a str,
@ -433,12 +448,7 @@ impl<'a> KeyValuePair<'a> {
<T as TryFrom<u64>>::Error: std::error::Error,
{
let val = self.value()?;
let numres = if val.starts_with("0x") || val.starts_with("0X") {
u64::from_str_radix(&val[2..], 16)
} else {
u64::from_str(val)
};
let num = self.handle_parse_err(numres)?;
let num = parse_hex_or_decimal(val)?;
self.handle_parse_err(T::try_from(num))
}
@ -704,4 +714,13 @@ mod tests {
assert!(kv.parse::<u32>().is_err());
assert!(kv.parse_numeric::<u32>().is_err());
}
#[test]
fn parse_hex_or_decimal_simple() {
assert_eq!(parse_hex_or_decimal("15").unwrap(), 15);
assert_eq!(parse_hex_or_decimal("0x15").unwrap(), 0x15);
assert_eq!(parse_hex_or_decimal("0X15").unwrap(), 0x15);
assert!(parse_hex_or_decimal("0xz").is_err());
assert!(parse_hex_or_decimal("hello world").is_err());
}
}

View file

@ -25,7 +25,7 @@ use crosvm::platform::GpuRenderServerParameters;
#[cfg(feature = "direct")]
use crosvm::DirectIoOption;
use crosvm::{
argument::{self, print_help, set_arguments, Argument},
argument::{self, parse_hex_or_decimal, print_help, set_arguments, Argument},
platform, BindMount, Config, DiskOption, Executable, FileBackedMappingParameters, GidMap,
SharedDir, TouchDeviceOption, VfioCommand, VhostUserFsOption, VhostUserOption,
VhostUserWlOption, VhostVsockDeviceParameter, VvuOption, DISK_ID_LEN,
@ -905,16 +905,6 @@ fn parse_battery_options(s: Option<&str>) -> argument::Result<BatteryType> {
Ok(battery_type)
}
#[cfg(feature = "direct")]
fn parse_hex_or_decimal(maybe_hex_string: &str) -> Result<u64, std::num::ParseIntError> {
// Parse string starting with 0x as hex and others as numbers.
let without_prefix = maybe_hex_string.strip_prefix("0x");
match without_prefix {
Some(hex_string) => u64::from_str_radix(hex_string, 16),
None => u64::from_str(maybe_hex_string),
}
}
#[cfg(feature = "direct")]
fn parse_direct_io_options(s: Option<&str>) -> argument::Result<DirectIoOption> {
let s = s.ok_or(argument::Error::ExpectedValue(String::from(