use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc;
use vortex_array::DeserializeMetadata;
use vortex_array::SerializeMetadata;
use vortex_array::dtype::DType;
use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use vortex_session::VortexSession;
use vortex_session::registry::ReadContext;
use crate::IntoLayout;
use crate::Layout;
use crate::LayoutChildType;
use crate::LayoutEncoding;
use crate::LayoutEncodingRef;
use crate::LayoutId;
use crate::LayoutReaderContext;
use crate::LayoutReaderRef;
use crate::LayoutRef;
use crate::children::LayoutChildren;
use crate::segments::SegmentId;
use crate::segments::SegmentSource;
pub struct LayoutBuildContext<'a> {
pub session: &'a VortexSession,
pub array_read_ctx: &'a ReadContext,
}
pub trait VTable: 'static + Sized + Send + Sync + Debug {
type Layout: 'static + Send + Sync + Clone + Debug + Deref<Target = dyn Layout> + IntoLayout;
type Encoding: 'static + Send + Sync + Deref<Target = dyn LayoutEncoding>;
type Metadata: SerializeMetadata + DeserializeMetadata + Debug;
fn id(encoding: &Self::Encoding) -> LayoutId;
fn encoding(layout: &Self::Layout) -> LayoutEncodingRef;
fn row_count(layout: &Self::Layout) -> u64;
fn dtype(layout: &Self::Layout) -> &DType;
fn metadata(layout: &Self::Layout) -> Self::Metadata;
fn segment_ids(layout: &Self::Layout) -> Vec<SegmentId>;
fn nchildren(layout: &Self::Layout) -> usize;
fn child(layout: &Self::Layout, idx: usize) -> VortexResult<LayoutRef>;
fn child_type(layout: &Self::Layout, idx: usize) -> LayoutChildType;
fn new_reader(
layout: &Self::Layout,
name: Arc<str>,
segment_source: Arc<dyn SegmentSource>,
session: &VortexSession,
ctx: &LayoutReaderContext,
) -> VortexResult<LayoutReaderRef>;
fn build(
encoding: &Self::Encoding,
dtype: &DType,
row_count: u64,
metadata: &<Self::Metadata as DeserializeMetadata>::Output,
segment_ids: Vec<SegmentId>,
children: &dyn LayoutChildren,
build_ctx: &LayoutBuildContext<'_>,
) -> VortexResult<Self::Layout>;
fn with_children(_layout: &mut Self::Layout, _children: Vec<LayoutRef>) -> VortexResult<()> {
vortex_bail!("with_children not implemented for this layout")
}
}
#[macro_export]
macro_rules! vtable {
($V:ident) => {
$crate::aliases::paste::paste! {
#[derive(Debug)]
pub struct $V;
impl AsRef<dyn $crate::Layout> for [<$V Layout>] {
fn as_ref(&self) -> &dyn $crate::Layout {
unsafe { &*(self as *const [<$V Layout>] as *const $crate::LayoutAdapter<$V>) }
}
}
impl std::ops::Deref for [<$V Layout>] {
type Target = dyn $crate::Layout;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const [<$V Layout>] as *const $crate::LayoutAdapter<$V>) }
}
}
impl $crate::IntoLayout for [<$V Layout>] {
fn into_layout(self) -> $crate::LayoutRef {
std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Layout>], $crate::LayoutAdapter::<$V>>(self) })
}
}
impl From<[<$V Layout>]> for $crate::LayoutRef {
fn from(value: [<$V Layout>]) -> $crate::LayoutRef {
use $crate::IntoLayout;
value.into_layout()
}
}
impl AsRef<dyn $crate::LayoutEncoding> for [<$V LayoutEncoding>] {
fn as_ref(&self) -> &dyn $crate::LayoutEncoding {
unsafe { &*(self as *const [<$V LayoutEncoding>] as *const $crate::LayoutEncodingAdapter<$V>) }
}
}
impl std::ops::Deref for [<$V LayoutEncoding>] {
type Target = dyn $crate::LayoutEncoding;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const [<$V LayoutEncoding>] as *const $crate::LayoutEncodingAdapter<$V>) }
}
}
}
};
}