#![allow(missing_docs)]
use crate::resp::{BufferDecoder, RespBuf, RespFrameParser, RespTapeMut, Value};
use bytes::BytesMut;
use tokio_util::codec::Decoder;
pub fn parse_frame(data: &[u8]) {
if data.is_empty() {
return;
}
let mut tape = RespTapeMut::default();
let _ = RespFrameParser::new(data, &mut tape).parse();
}
pub fn decode_chunked(data: &[u8], splits: &[u8]) {
let mut decoder = BufferDecoder::new();
let mut buf = BytesMut::new();
let mut bounds: Vec<usize> = splits
.iter()
.map(|&s| (s as usize).min(data.len()))
.collect();
bounds.sort_unstable();
bounds.push(data.len());
let mut cursor = 0usize;
for bound in bounds {
if bound > cursor {
buf.extend_from_slice(&data[cursor..bound]);
cursor = bound;
}
while let Ok(Some(_)) = decoder.decode(&mut buf) {}
}
}
pub fn deserialize_to_value(data: &[u8]) -> Option<Value> {
if data.is_empty() {
return None;
}
RespBuf::from_slice(data).to::<Value>().ok()
}
pub fn value_deserializer_roundtrip(data: &[u8]) {
if deserialize_to_value(data).is_none() {
return;
}
macro_rules! target {
($t:ty) => {
if let Some(value) = deserialize_to_value(data) {
let _ = value.into::<$t>();
}
};
}
target!(String);
target!(i64);
target!(u64);
target!(f64);
target!(bool);
target!(Vec<String>);
target!(Vec<i64>);
target!(std::collections::HashMap<String, String>);
target!(Vec<Vec<u8>>);
}