implement value listing

This commit is contained in:
Ondrej Novak 2026-06-06 22:30:28 +02:00
parent c771f8698e
commit 8e42d763fe
Signed by: handy
SSH Key Fingerprint: SHA256:jlNm8ijkaMl4X7+nn3zBFTJufdQgT4unKJoZVH6kYTM
4 changed files with 105 additions and 9 deletions

41
Cargo.lock generated
View File

@ -24,6 +24,15 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "aligned"
version = "0.4.3"
@ -929,6 +938,9 @@ dependencies = [
[[package]]
name = "protocol"
version = "0.1.0"
dependencies = [
"regex",
]
[[package]]
name = "pxfm"
@ -1081,6 +1093,35 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rgb"
version = "0.8.53"

View File

@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2024"
[dependencies]
regex = "1"

View File

@ -4,6 +4,18 @@ pub fn create_request_message(value: &String) -> String {
format!("GETVAL {}\n", value)
}
pub fn create_list_message() -> String {
format!("LISTVAL\n")
}
pub fn parse_list_response(lines: Vec<String>) -> Vec<String> {
lines
.iter()
.filter_map(|l| l.split(" ").last())
.map(|l| l.into())
.collect()
}
pub fn parse_response_header(header: String) -> Result<i32, ProtocolError> {
let num_values_raw = header
.split(" ")
@ -118,4 +130,27 @@ mod tests {
assert!(result.is_err());
assert_eq!(result, Err(ProtocolError::EmptyResponse));
}
#[test]
fn test_parse_list_response() {
let resp = vec![
"1780776337.692 tp-on/cpu-9/cpu-steal",
"1780776337.692 tp-on/cpu-9/cpu-system",
"1780776337.692 tp-on/cpu-9/cpu-user",
"1780776337.692 tp-on/cpu-9/cpu-wait",
]
.iter()
.map(|s| s.to_string())
.collect();
let result = parse_list_response(resp);
assert_eq!(
result,
vec![
"tp-on/cpu-9/cpu-steal",
"tp-on/cpu-9/cpu-system",
"tp-on/cpu-9/cpu-user",
"tp-on/cpu-9/cpu-wait",
]
);
}
}

View File

@ -2,7 +2,10 @@ use std::io::{Read, Write};
use std::os::unix::net::UnixStream;
use crate::err::ProtocolError;
use crate::message::{create_request_message, parse_response_header, parse_response_message};
use crate::message::{
create_list_message, create_request_message, parse_list_response, parse_response_header,
parse_response_message,
};
pub struct Protocol {
socket: UnixStream,
@ -34,6 +37,27 @@ impl Protocol {
pub fn get(&mut self, path: String, name: String) -> Result<f32, ProtocolError> {
let req = create_request_message(&path);
let lines = self.rpc(&req)?;
if lines.len() < 1 {
Err(ProtocolError::ValueNotFound(name, vec![]))
} else {
parse_response_message(lines, name)
}
}
pub fn list(&mut self, path_regex: &Regex) -> Result<Vec<String>, ProtocolError> {
let req = create_list_message();
let lines = self.rpc(&req)?;
let values = parse_list_response(lines);
Ok(values
.into_iter()
.filter(|v| path_regex.is_match(v))
.collect())
}
fn rpc(&mut self, req: &str) -> Result<Vec<String>, ProtocolError> {
let raw_req = req.as_bytes();
self.socket
.write_all(raw_req)
@ -41,13 +65,8 @@ impl Protocol {
let header = self.read_line()?;
let num_values = parse_response_header(header)?;
if num_values < 1 {
Err(ProtocolError::ValueNotFound(name, vec![]))
} else {
let lines = (0..num_values)
(0..num_values)
.map(|_| self.read_line())
.collect::<Result<Vec<String>, ProtocolError>>()?;
parse_response_message(lines, name)
}
.collect::<Result<Vec<String>, ProtocolError>>()
}
}