use noxu_db::DatabaseEntry;
use crate::entry_binding::EntryBinding;
use crate::error::{BindError, Result};
#[derive(Debug, Clone, Copy, Default)]
pub struct RecordNumberBinding;
impl RecordNumberBinding {
pub fn new() -> Self {
Self
}
pub fn entry_to_record_number(entry: &DatabaseEntry) -> Result<u64> {
let data = entry.data();
if data.len() < 8 {
return Err(BindError::BufferUnderflow {
needed: 8,
available: data.len(),
});
}
let mut bytes = [0u8; 8];
bytes.copy_from_slice(&data[..8]);
Ok(u64::from_be_bytes(bytes))
}
pub fn record_number_to_entry(number: u64, entry: &mut DatabaseEntry) {
entry.set_data(&number.to_be_bytes());
}
}
impl EntryBinding<u64> for RecordNumberBinding {
fn entry_to_object(&self, entry: &DatabaseEntry) -> Result<u64> {
Self::entry_to_record_number(entry)
}
fn object_to_entry(
&self,
object: &u64,
entry: &mut DatabaseEntry,
) -> Result<()> {
Self::record_number_to_entry(*object, entry);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_round_trip() {
let binding = RecordNumberBinding::new();
let number = 12345u64;
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&number, &mut entry).unwrap();
let result = binding.entry_to_object(&entry).unwrap();
assert_eq!(number, result);
}
#[test]
fn test_zero() {
let binding = RecordNumberBinding::new();
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&0u64, &mut entry).unwrap();
assert_eq!(0u64, binding.entry_to_object(&entry).unwrap());
}
#[test]
fn test_max() {
let binding = RecordNumberBinding::new();
let mut entry = DatabaseEntry::new();
binding.object_to_entry(&u64::MAX, &mut entry).unwrap();
assert_eq!(u64::MAX, binding.entry_to_object(&entry).unwrap());
}
#[test]
fn test_underflow() {
let binding = RecordNumberBinding::new();
let entry = DatabaseEntry::from_bytes(&[1, 2, 3]);
let result = binding.entry_to_object(&entry);
assert!(result.is_err());
}
}