From ad521fd4e47783affe2e1226a77267070a670645 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 8 Nov 2021 16:52:53 +0100 Subject: [PATCH] option_parser: Create generic type Tuple Creates a new generic type Tuple so that the same implementation of FromStr trait can be reused for both parsing a list of two integers and parsing a list of one integer associated with a list of integers. This anticipates the need for retrieving sublists, which will be needed when trying to describe the host CPU affinity for every vCPU. Signed-off-by: Sebastien Boeuf --- option_parser/src/lib.rs | 46 ++++++++++++++++++++++++++++------------ vmm/src/config.rs | 4 ++-- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/option_parser/src/lib.rs b/option_parser/src/lib.rs index 3e54e4fb9..86424ed95 100644 --- a/option_parser/src/lib.rs +++ b/option_parser/src/lib.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; use std::fmt; +use std::num::ParseIntError; use std::str::FromStr; #[derive(Default)] @@ -240,17 +241,39 @@ impl FromStr for IntegerList { } } -pub struct TupleTwoIntegers(pub Vec<(u64, u64)>); +pub trait TupleValue { + fn parse_value(input: &str) -> Result + where + Self: Sized; +} -pub enum TupleTwoIntegersParseError { +impl TupleValue for u64 { + fn parse_value(input: &str) -> Result { + input.parse::() + } +} + +impl TupleValue for Vec { + fn parse_value(input: &str) -> Result { + input + .trim_matches(|c| c == '[' || c == ']') + .split(',') + .map(|i| i.parse::()) + .collect::, _>>() + } +} + +pub struct Tuple(pub Vec<(u64, T)>); + +pub enum TupleError { InvalidValue(String), } -impl FromStr for TupleTwoIntegers { - type Err = TupleTwoIntegersParseError; +impl FromStr for Tuple { + type Err = TupleError; fn from_str(s: &str) -> std::result::Result { - let mut list = Vec::new(); + let mut list: Vec<(u64, T)> = Vec::new(); let tuples_list: Vec<&str> = s .trim() .trim_matches(|c| c == '[' || c == ']') @@ -261,22 +284,19 @@ impl FromStr for TupleTwoIntegers { let items: Vec<&str> = tuple.split('@').collect(); if items.len() != 2 { - return Err(TupleTwoIntegersParseError::InvalidValue( - (*tuple).to_string(), - )); + return Err(TupleError::InvalidValue((*tuple).to_string())); } let item1 = items[0] .parse::() - .map_err(|_| TupleTwoIntegersParseError::InvalidValue(items[0].to_owned()))?; - let item2 = items[1] - .parse::() - .map_err(|_| TupleTwoIntegersParseError::InvalidValue(items[1].to_owned()))?; + .map_err(|_| TupleError::InvalidValue(items[0].to_owned()))?; + let item2 = TupleValue::parse_value(items[1]) + .map_err(|_| TupleError::InvalidValue(items[1].to_owned()))?; list.push((item1, item2)); } - Ok(TupleTwoIntegers(list)) + Ok(Tuple(list)) } } diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 667e8fd53..ac0373ee6 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -6,7 +6,7 @@ use clap::ArgMatches; use net_util::MacAddr; use option_parser::{ - ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, TupleTwoIntegers, + ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, Tuple, }; use std::collections::HashMap; use std::convert::From; @@ -1942,7 +1942,7 @@ impl NumaConfig { .map_err(Error::ParseNuma)? .map(|v| v.0.iter().map(|e| *e as u8).collect()); let distances = parser - .convert::("distances") + .convert::>("distances") .map_err(Error::ParseNuma)? .map(|v| { v.0.iter()