145 lines
4.5 KiB
Rust
145 lines
4.5 KiB
Rust
//! Serialization and deserialization for RadixTree nodes.
|
|
|
|
use crate::error::Error;
|
|
use crate::node::{Node, NodeRef};
|
|
use std::convert::TryInto;
|
|
use std::io::{Cursor, Read, Write};
|
|
use std::mem::size_of;
|
|
|
|
/// Current binary format version.
|
|
const VERSION: u8 = 1;
|
|
|
|
impl Node {
|
|
/// Serializes a node to bytes for storage.
|
|
pub fn serialize(&self) -> Vec<u8> {
|
|
let mut buffer = Vec::new();
|
|
|
|
// Add version byte
|
|
buffer.push(VERSION);
|
|
|
|
// Add key segment
|
|
write_string(&mut buffer, &self.key_segment);
|
|
|
|
// Add value as []u8
|
|
write_u16(&mut buffer, self.value.len() as u16);
|
|
buffer.extend_from_slice(&self.value);
|
|
|
|
// Add children
|
|
write_u16(&mut buffer, self.children.len() as u16);
|
|
for child in &self.children {
|
|
write_string(&mut buffer, &child.key_part);
|
|
write_u32(&mut buffer, child.node_id);
|
|
}
|
|
|
|
// Add leaf flag
|
|
buffer.push(if self.is_leaf { 1 } else { 0 });
|
|
|
|
buffer
|
|
}
|
|
|
|
/// Deserializes bytes to a node.
|
|
pub fn deserialize(data: &[u8]) -> Result<Self, Error> {
|
|
if data.is_empty() {
|
|
return Err(Error::Deserialization("Empty data".to_string()));
|
|
}
|
|
|
|
let mut cursor = Cursor::new(data);
|
|
|
|
// Read and verify version
|
|
let mut version_byte = [0u8; 1];
|
|
cursor.read_exact(&mut version_byte)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read version byte: {}", e)))?;
|
|
|
|
if version_byte[0] != VERSION {
|
|
return Err(Error::Deserialization(
|
|
format!("Invalid version byte: expected {}, got {}", VERSION, version_byte[0])
|
|
));
|
|
}
|
|
|
|
// Read key segment
|
|
let key_segment = read_string(&mut cursor)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read key segment: {}", e)))?;
|
|
|
|
// Read value as []u8
|
|
let value_len = read_u16(&mut cursor)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read value length: {}", e)))?;
|
|
|
|
let mut value = vec![0u8; value_len as usize];
|
|
cursor.read_exact(&mut value)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read value: {}", e)))?;
|
|
|
|
// Read children
|
|
let children_len = read_u16(&mut cursor)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read children length: {}", e)))?;
|
|
|
|
let mut children = Vec::with_capacity(children_len as usize);
|
|
for _ in 0..children_len {
|
|
let key_part = read_string(&mut cursor)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read child key part: {}", e)))?;
|
|
|
|
let node_id = read_u32(&mut cursor)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read child node ID: {}", e)))?;
|
|
|
|
children.push(NodeRef {
|
|
key_part,
|
|
node_id,
|
|
});
|
|
}
|
|
|
|
// Read leaf flag
|
|
let mut is_leaf_byte = [0u8; 1];
|
|
cursor.read_exact(&mut is_leaf_byte)
|
|
.map_err(|e| Error::Deserialization(format!("Failed to read leaf flag: {}", e)))?;
|
|
|
|
let is_leaf = is_leaf_byte[0] == 1;
|
|
|
|
Ok(Node {
|
|
key_segment,
|
|
value,
|
|
children,
|
|
is_leaf,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Helper functions for serialization
|
|
|
|
fn write_string(buffer: &mut Vec<u8>, s: &str) {
|
|
let bytes = s.as_bytes();
|
|
write_u16(buffer, bytes.len() as u16);
|
|
buffer.extend_from_slice(bytes);
|
|
}
|
|
|
|
fn write_u16(buffer: &mut Vec<u8>, value: u16) {
|
|
buffer.extend_from_slice(&value.to_le_bytes());
|
|
}
|
|
|
|
fn write_u32(buffer: &mut Vec<u8>, value: u32) {
|
|
buffer.extend_from_slice(&value.to_le_bytes());
|
|
}
|
|
|
|
// Helper functions for deserialization
|
|
|
|
fn read_string(cursor: &mut Cursor<&[u8]>) -> std::io::Result<String> {
|
|
let len = read_u16(cursor)? as usize;
|
|
let mut bytes = vec![0u8; len];
|
|
cursor.read_exact(&mut bytes)?;
|
|
|
|
String::from_utf8(bytes)
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
|
|
}
|
|
|
|
fn read_u16(cursor: &mut Cursor<&[u8]>) -> std::io::Result<u16> {
|
|
let mut bytes = [0u8; size_of::<u16>()];
|
|
cursor.read_exact(&mut bytes)?;
|
|
|
|
Ok(u16::from_le_bytes(bytes))
|
|
}
|
|
|
|
fn read_u32(cursor: &mut Cursor<&[u8]>) -> std::io::Result<u32> {
|
|
let mut bytes = [0u8; size_of::<u32>()];
|
|
cursor.read_exact(&mut bytes)?;
|
|
|
|
Ok(u32::from_le_bytes(bytes))
|
|
}
|