use std::cmp::Ordering;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HFileRecord {
pub key: Vec<u8>,
pub value: Vec<u8>,
}
impl HFileRecord {
pub fn new(key: Vec<u8>, value: Vec<u8>) -> Self {
Self { key, value }
}
pub fn from_str_key(key: &str, value: Vec<u8>) -> Self {
Self {
key: key.as_bytes().to_vec(),
value,
}
}
pub fn key_as_str(&self) -> Option<&str> {
std::str::from_utf8(&self.key).ok()
}
pub fn key(&self) -> &[u8] {
&self.key
}
pub fn value(&self) -> &[u8] {
&self.value
}
pub fn is_deleted(&self) -> bool {
self.value.is_empty()
}
}
impl PartialOrd for HFileRecord {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for HFileRecord {
fn cmp(&self, other: &Self) -> Ordering {
self.key.cmp(&other.key)
}
}
impl std::fmt::Display for HFileRecord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.key_as_str() {
Some(key) => write!(
f,
"HFileRecord{{key={}, value_len={}}}",
key,
self.value.len()
),
None => write!(
f,
"HFileRecord{{key=<binary {} bytes>, value_len={}}}",
self.key.len(),
self.value.len()
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hfile_record_creation() {
let record = HFileRecord::new(b"test-key".to_vec(), b"test-value".to_vec());
assert_eq!(record.key_as_str(), Some("test-key"));
assert_eq!(record.value(), b"test-value");
assert!(!record.is_deleted());
}
#[test]
fn test_hfile_record_from_str() {
let record = HFileRecord::from_str_key("my-key", b"my-value".to_vec());
assert_eq!(record.key_as_str(), Some("my-key"));
assert_eq!(record.value(), b"my-value");
}
#[test]
fn test_hfile_record_deleted() {
let record = HFileRecord::new(b"deleted-key".to_vec(), vec![]);
assert!(record.is_deleted());
}
#[test]
fn test_hfile_record_ordering() {
let r1 = HFileRecord::from_str_key("aaa", vec![1]);
let r2 = HFileRecord::from_str_key("bbb", vec![2]);
let r3 = HFileRecord::from_str_key("aaa", vec![3]);
assert!(r1 < r2);
assert_eq!(r1.cmp(&r3), Ordering::Equal); }
#[test]
fn test_hfile_record_display() {
let record = HFileRecord::from_str_key("test", b"value".to_vec());
let display = format!("{record}");
assert!(display.contains("test"));
assert!(display.contains("value_len=5"));
}
}