use std::fmt;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::sync::Arc;
use vortex_buffer::ByteBuffer;
use vortex_error::VortexResult;
use vortex_error::vortex_ensure;
use vortex_session::VortexSession;
use crate::ArrayRef;
use crate::IntoArray;
use crate::array::Array;
use crate::array::ArrayId;
use crate::array::VTable;
use crate::buffer::BufferHandle;
use crate::dtype::DType;
use crate::serde::ArrayChildren;
pub type ArrayPluginRef = Arc<dyn ArrayPlugin>;
#[derive(Clone, Debug)]
pub struct ArraySerialization {
pub serialized_id: ArrayId,
pub metadata: Vec<u8>,
pub buffers: Vec<ByteBuffer>,
pub children: Vec<ArrayRef>,
}
impl ArraySerialization {
pub fn new(
serialized_id: ArrayId,
metadata: Vec<u8>,
buffers: Vec<ByteBuffer>,
children: Vec<ArrayRef>,
) -> Self {
Self {
serialized_id,
metadata,
buffers,
children,
}
}
pub fn from_array(serialized_id: ArrayId, array: &ArrayRef, metadata: Vec<u8>) -> Self {
Self::new(serialized_id, metadata, array.buffers(), array.children())
}
}
pub struct ArrayDeserialization<'a> {
pub serialized_id: ArrayId,
pub dtype: &'a DType,
pub len: usize,
pub metadata: &'a [u8],
pub buffers: &'a [BufferHandle],
pub children: &'a dyn ArrayChildren,
}
impl<'a> ArrayDeserialization<'a> {
pub fn new(
serialized_id: ArrayId,
dtype: &'a DType,
len: usize,
metadata: &'a [u8],
buffers: &'a [BufferHandle],
children: &'a dyn ArrayChildren,
) -> Self {
Self {
serialized_id,
dtype,
len,
metadata,
buffers,
children,
}
}
}
pub trait ArrayPlugin: 'static + Send + Sync {
fn id(&self) -> ArrayId;
fn serialized_ids(&self) -> Vec<ArrayId> {
vec![self.id()]
}
fn serialize(
&self,
array: &ArrayRef,
session: &VortexSession,
) -> VortexResult<Option<ArraySerialization>>;
fn deserialize(
&self,
parts: ArrayDeserialization<'_>,
session: &VortexSession,
) -> VortexResult<ArrayRef>;
fn is_supported_encoding(&self, id: &ArrayId) -> bool {
self.id() == *id
}
}
impl Debug for dyn ArrayPlugin {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("ArrayPlugin").field(&self.id()).finish()
}
}
impl<V: VTable> ArrayPlugin for V {
fn id(&self) -> ArrayId {
VTable::id(self)
}
fn serialize(
&self,
array: &ArrayRef,
session: &VortexSession,
) -> VortexResult<Option<ArraySerialization>> {
vortex_ensure!(
self.id() == array.encoding_id(),
"array plugin {} cannot serialize in-memory array {}",
self.id(),
array.encoding_id(),
);
Ok(V::serialize(array.as_::<V>(), session)?
.map(|metadata| ArraySerialization::from_array(self.id(), array, metadata)))
}
fn deserialize(
&self,
parts: ArrayDeserialization<'_>,
session: &VortexSession,
) -> VortexResult<ArrayRef> {
vortex_ensure!(
self.id() == parts.serialized_id,
"array plugin {} does not recognize serialized ID {}",
self.id(),
parts.serialized_id,
);
Ok(Array::<V>::try_from_parts(V::deserialize(
self,
parts.dtype,
parts.len,
parts.metadata,
parts.buffers,
parts.children,
session,
)?)?
.into_array())
}
}