use crate::error::{Error, Result};
use crate::metadata::{KvFormat, RowType};
use crate::row::compacted::{CompactedRow, CompactedRowDeserializer};
use std::sync::Arc;
pub trait RowDecoder: Send + Sync {
fn decode<'a>(&self, data: &'a [u8]) -> CompactedRow<'a>;
}
pub struct CompactedRowDecoder {
field_count: usize,
deserializer: Arc<CompactedRowDeserializer<'static>>,
}
impl CompactedRowDecoder {
pub fn new(row_type: RowType) -> Self {
let field_count = row_type.fields().len();
let deserializer = Arc::new(CompactedRowDeserializer::new_from_owned(row_type));
Self {
field_count,
deserializer,
}
}
}
impl RowDecoder for CompactedRowDecoder {
fn decode<'a>(&self, data: &'a [u8]) -> CompactedRow<'a> {
CompactedRow::deserialize(Arc::clone(&self.deserializer), self.field_count, data)
}
}
pub struct RowDecoderFactory;
impl RowDecoderFactory {
pub fn create(kv_format: KvFormat, row_type: RowType) -> Result<Arc<dyn RowDecoder>> {
match kv_format {
KvFormat::COMPACTED => Ok(Arc::new(CompactedRowDecoder::new(row_type))),
KvFormat::INDEXED => Err(Error::UnsupportedOperation {
message: "INDEXED format is not yet supported".to_string(),
}),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::metadata::DataTypes;
use crate::row::InternalRow;
use crate::row::binary::BinaryWriter;
use crate::row::compacted::CompactedRowWriter;
#[test]
fn test_compacted_row_decoder() {
let mut writer = CompactedRowWriter::new(2);
writer.write_int(42);
writer.write_string("hello");
let data = writer.to_bytes();
let row_type = RowType::with_data_types(vec![DataTypes::int(), DataTypes::string()]);
let decoder = CompactedRowDecoder::new(row_type);
let row = decoder.decode(&data);
assert_eq!(row.get_field_count(), 2);
assert_eq!(row.get_int(0).unwrap(), 42);
assert_eq!(row.get_string(1).unwrap(), "hello");
}
#[test]
fn test_row_decoder_factory() {
let row_type = RowType::with_data_types(vec![DataTypes::int(), DataTypes::string()]);
let decoder = RowDecoderFactory::create(KvFormat::COMPACTED, row_type).unwrap();
let mut writer = CompactedRowWriter::new(2);
writer.write_int(100);
writer.write_string("world");
let data = writer.to_bytes();
let row = decoder.decode(&data);
assert_eq!(row.get_int(0).unwrap(), 100);
assert_eq!(row.get_string(1).unwrap(), "world");
}
}