use bytes::Bytes;
use foundation_arrow::arrow_array::RecordBatch;
use foundation_arrow::{decode_ipc, encode_ipc, FromArrow, ToArrow};
use super::{Codec, CodecError, CodecFor};
const NAME: &str = "arrow";
#[derive(Debug, Clone, Copy, Default)]
pub struct ArrowCodec;
impl Codec for ArrowCodec {
fn name(&self) -> &str {
NAME
}
fn is_binary(&self) -> bool {
true
}
}
impl<M: ToArrow + FromArrow> CodecFor<M> for ArrowCodec {
fn marshal(&self, message: &M) -> Result<Bytes, CodecError> {
let batch = message
.to_arrow()
.map_err(|e| CodecError::encode(NAME, e.to_string()))?;
let bytes = encode_ipc(&batch).map_err(|e| CodecError::encode(NAME, e.to_string()))?;
Ok(Bytes::from(bytes))
}
fn unmarshal(&self, data: Bytes) -> Result<M, CodecError> {
let batch = decode_ipc(&data).map_err(|e| CodecError::decode(NAME, e.to_string()))?;
M::from_arrow(&batch).map_err(|e| CodecError::decode(NAME, e.to_string()))
}
fn marshal_stable(&self, message: &M) -> Result<Bytes, CodecError> {
self.marshal(message)
}
fn marshal_append(&self, buf: &mut Vec<u8>, message: &M) -> Result<(), CodecError> {
let bytes = self.marshal(message)?;
buf.extend_from_slice(&bytes);
Ok(())
}
}
impl ArrowCodec {
pub fn unmarshal_batch(&self, data: Bytes) -> Result<RecordBatch, CodecError> {
decode_ipc(&data).map_err(|e| CodecError::decode(NAME, e.to_string()))
}
}