net_util: Fix map_err losing the inner error

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-01-24 08:30:50 +01:00
parent f5a52eda2b
commit 06396593c9
2 changed files with 21 additions and 10 deletions

View File

@ -7,6 +7,7 @@
use rand::Rng; use rand::Rng;
use std::fmt; use std::fmt;
use std::io;
use std::result::Result; use std::result::Result;
use serde::de::{Deserialize, Deserializer, Error}; use serde::de::{Deserialize, Deserializer, Error};
@ -20,23 +21,31 @@ pub struct MacAddr {
} }
impl MacAddr { impl MacAddr {
// The error contains the str that failed to be parsed, for nicer error message generation. pub fn parse_str<S>(s: &S) -> Result<MacAddr, io::Error>
pub fn parse_str<S>(s: &S) -> Result<MacAddr, &str>
where where
S: AsRef<str> + ?Sized, S: AsRef<str> + ?Sized,
{ {
let v: Vec<&str> = s.as_ref().split(':').collect(); let v: Vec<&str> = s.as_ref().split(':').collect();
let mut bytes = [0u8; MAC_ADDR_LEN]; let mut bytes = [0u8; MAC_ADDR_LEN];
let common_err = Err(io::Error::new(
io::ErrorKind::Other,
format!("parsing of {} into a MAC address failed", s.as_ref()),
));
if v.len() != MAC_ADDR_LEN { if v.len() != MAC_ADDR_LEN {
return Err(s.as_ref()); return common_err;
} }
for i in 0..MAC_ADDR_LEN { for i in 0..MAC_ADDR_LEN {
if v[i].len() != 2 { if v[i].len() != 2 {
return Err(s.as_ref()); return common_err;
} }
bytes[i] = u8::from_str_radix(v[i], 16).map_err(|_| s.as_ref())?; bytes[i] = u8::from_str_radix(v[i], 16).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("parsing of {} into a MAC address failed: {}", s.as_ref(), e),
)
})?;
} }
Ok(MacAddr { bytes }) Ok(MacAddr { bytes })
@ -106,7 +115,8 @@ impl<'de> Deserialize<'de> for MacAddr {
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let s = String::deserialize(deserializer)?; let s = String::deserialize(deserializer)?;
MacAddr::parse_str(&s).map_err(|_| D::Error::custom("The provided MAC address is invalid.")) MacAddr::parse_str(&s)
.map_err(|e| D::Error::custom(format!("The provided MAC address is invalid: {}", e)))
} }
} }

View File

@ -8,6 +8,7 @@ extern crate vm_virtio;
use clap::ArgMatches; use clap::ArgMatches;
use net_util::MacAddr; use net_util::MacAddr;
use std::convert::From; use std::convert::From;
use std::io;
use std::net::AddrParseError; use std::net::AddrParseError;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::path::PathBuf; use std::path::PathBuf;
@ -23,7 +24,7 @@ pub const DEFAULT_QUEUE_SIZE_VUBLK: u16 = 128;
/// Errors associated with VM configuration parameters. /// Errors associated with VM configuration parameters.
#[derive(Debug)] #[derive(Debug)]
pub enum Error<'a> { pub enum Error {
/// Failed parsing cpus parameters. /// Failed parsing cpus parameters.
ParseCpusParams(std::num::ParseIntError), ParseCpusParams(std::num::ParseIntError),
/// Unexpected vCPU parameter /// Unexpected vCPU parameter
@ -45,7 +46,7 @@ pub enum Error<'a> {
/// Failed parsing network mask parameter. /// Failed parsing network mask parameter.
ParseNetMaskParam(AddrParseError), ParseNetMaskParam(AddrParseError),
/// Failed parsing network mac parameter. /// Failed parsing network mac parameter.
ParseNetMacParam(&'a str), ParseNetMacParam(io::Error),
/// Failed parsing network queue number parameter. /// Failed parsing network queue number parameter.
ParseNetNumQueuesParam(std::num::ParseIntError), ParseNetNumQueuesParam(std::num::ParseIntError),
/// Failed parsing network queue size parameter. /// Failed parsing network queue size parameter.
@ -71,7 +72,7 @@ pub enum Error<'a> {
/// Both console and serial are tty. /// Both console and serial are tty.
ParseTTYParam, ParseTTYParam,
/// Failed parsing vhost-user-net mac parameter. /// Failed parsing vhost-user-net mac parameter.
ParseVuNetMacParam(&'a str), ParseVuNetMacParam(io::Error),
/// Failed parsing vhost-user sock parameter. /// Failed parsing vhost-user sock parameter.
ParseVuSockParam, ParseVuSockParam,
/// Failed parsing vhost-user queue number parameter. /// Failed parsing vhost-user queue number parameter.
@ -91,7 +92,7 @@ pub enum Error<'a> {
/// Failed parsing generic on|off parameter. /// Failed parsing generic on|off parameter.
ParseOnOff, ParseOnOff,
} }
pub type Result<'a, T> = result::Result<T, Error<'a>>; pub type Result<T> = result::Result<T, Error>;
pub struct VmParams<'a> { pub struct VmParams<'a> {
pub cpus: &'a str, pub cpus: &'a str,