Consolidate hex string to u32 conversion

Rather than having lots of "cpu.replace("0x", "").str_radix(...)
calls around, move to a single, unit-tested function in lqos_utils
and use it repeatedly.
This commit is contained in:
Herbert Wolverson
2023-03-03 14:17:31 +00:00
parent 308453fecf
commit 433e7ac877
9 changed files with 72 additions and 24 deletions

8
src/rust/Cargo.lock generated
View File

@@ -1365,6 +1365,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"lqos_bus",
"lqos_utils",
"nix",
"pyo3",
"sysinfo",
@@ -2509,9 +2510,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.25.0"
version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [
"autocfg",
"bytes",
@@ -2524,7 +2525,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.42.0",
"windows-sys 0.45.0",
]
[[package]]
@@ -3063,6 +3064,7 @@ dependencies = [
"anyhow",
"clap 4.1.8",
"lqos_bus",
"lqos_utils",
"tokio",
]

View File

@@ -10,6 +10,7 @@ crate-type = ["cdylib"]
[dependencies]
pyo3 = "0"
lqos_bus = { path = "../lqos_bus" }
lqos_utils = { path = "../lqos_utils" }
tokio = { version = "1", features = [ "rt", "macros", "net", "io-util", "time" ] }
anyhow = "1"
sysinfo = "0"

View File

@@ -1,4 +1,5 @@
use lqos_bus::{BusRequest, BusResponse, TcHandle};
use lqos_utils::hex_string::read_hex_string;
use nix::libc::getpid;
use pyo3::{
exceptions::PyOSError, pyclass, pyfunction, pymodule, types::PyModule,
@@ -122,7 +123,7 @@ fn parse_add_ip(
Ok(BusRequest::MapIpToFlow {
ip_address: ip.to_string(),
tc_handle: TcHandle::from_string(classid)?,
cpu: u32::from_str_radix(&cpu.replace("0x", ""), 16)?, // Force HEX representation
cpu: read_hex_string(cpu)?, // Force HEX representation
upload,
})
}

View File

@@ -8,18 +8,6 @@ use queue_network::QueueNetwork;
use queue_node::QueueNode;
use thiserror::Error;
fn read_hex_string(s: &str) -> Result<u32, HexParseError> {
let result = u32::from_str_radix(&s.replace("0x", ""), 16);
match result {
Ok(data) => Ok(data),
Err(e) => {
error!("Unable to convert {s} to a u32");
error!("{:?}", e);
Err(HexParseError::ParseError)
}
}
}
pub(crate) fn read_queueing_structure(
) -> Result<Vec<QueueNode>, QueueStructureError> {
// Note: the ? is allowed because the sub-types return a QueueStructureError and handle logging.
@@ -28,12 +16,6 @@ pub(crate) fn read_queueing_structure(
Ok(flattened)
}
#[derive(Error, Debug)]
pub enum HexParseError {
#[error("Unable to decode string into valid hex")]
ParseError,
}
#[derive(Error, Debug)]
pub enum QueueStructureError {
#[error("unable to parse u64")]

View File

@@ -1,4 +1,5 @@
use super::{read_hex_string, QueueStructureError};
use lqos_utils::hex_string::read_hex_string;
use super::QueueStructureError;
use log::error;
use lqos_bus::TcHandle;
use serde_json::Value;

View File

@@ -0,0 +1,58 @@
use log::error;
use thiserror::Error;
/// `read_hex_string` converts a string from C-friendly Hex format
/// (e.g. `0xC12`) into a hexadecimal `u32`.
///
/// ## Parameters
///
/// * `s`: the string to attempt to parse.
///
/// ## Returns
///
/// Either a converted `u32` or a `HexParseError`.
///
/// ## Example
///
/// ```rust
/// use lqos_utils::hex_string::read_hex_string;
/// assert_eq!(read_hex_string("0x12AD").unwrap(), 4781);
/// ```
pub fn read_hex_string(s: &str) -> Result<u32, HexParseError> {
let result = u32::from_str_radix(&s.replace("0x", ""), 16);
match result {
Ok(data) => Ok(data),
Err(e) => {
error!("Unable to convert {s} to a u32");
error!("{:?}", e);
Err(HexParseError::ParseError)
}
}
}
/// `HexParseError` is an error type defining what can go wrong
/// parsing a string into a `u32` hex number.
#[derive(Error, Debug)]
pub enum HexParseError {
#[error("Unable to decode string into valid hex")]
ParseError,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hex_string_success() {
assert_eq!(read_hex_string("0x12AD").unwrap(), 4781);
assert_eq!(read_hex_string("12AD").unwrap(), 4781);
assert_eq!(read_hex_string("0x12ad").unwrap(), 4781);
assert_eq!(read_hex_string("12Ad").unwrap(), 4781);
}
#[test]
fn hex_string_fail() {
assert!(read_hex_string("0xG00F").is_err());
assert!(read_hex_string("G00F").is_err());
}
}

View File

@@ -4,3 +4,4 @@ pub mod file_watcher;
pub mod packet_scale;
mod string_table_enum;
pub mod unix_time;
pub mod hex_string;

View File

@@ -8,3 +8,4 @@ clap = { version = "4", features = ["derive"] }
tokio = { version = "1", features = [ "rt", "macros", "net", "io-util", "time" ] }
anyhow = "1"
lqos_bus = { path = "../lqos_bus" }
lqos_utils = { path = "../lqos_utils" }

View File

@@ -1,6 +1,7 @@
use anyhow::{Error, Result};
use clap::{Parser, Subcommand};
use lqos_bus::{bus_request, BusRequest, BusResponse, IpMapping, TcHandle};
use lqos_utils::hex_string::read_hex_string;
use std::process::exit;
#[derive(Parser)]
@@ -99,7 +100,7 @@ fn parse_add_ip(
Ok(BusRequest::MapIpToFlow {
ip_address: ip.to_string(),
tc_handle: TcHandle::from_string(classid)?,
cpu: u32::from_str_radix(&cpu.replace("0x", ""), 16)?, // Force HEX representation
cpu: read_hex_string(cpu)?, // Force HEX representation
upload: upload.is_some(),
})
}