1use std::fmt::{Debug, Display};
5use std::hash::Hash;
6use std::ops::Deref;
7
8use vortex_array::{ArrayRef, DeserializeMetadata, SerializeMetadata};
9use vortex_dtype::DType;
10use vortex_error::VortexResult;
11
12use crate::{
13 AnalysisExpr, ExprEncoding, ExprEncodingRef, ExprId, ExprRef, IntoExpr, Scope, VortexExpr,
14};
15
16pub trait VTable: 'static + Sized + Send + Sync + Debug {
17 type Expr: 'static
18 + Send
19 + Sync
20 + Clone
21 + Debug
22 + Display
23 + PartialEq
24 + Hash
25 + Deref<Target = dyn VortexExpr>
26 + IntoExpr
27 + AnalysisExpr;
28 type Encoding: 'static + Send + Sync + Deref<Target = dyn ExprEncoding>;
29 type Metadata: SerializeMetadata + DeserializeMetadata + Debug;
30
31 fn id(encoding: &Self::Encoding) -> ExprId;
33
34 fn encoding(expr: &Self::Expr) -> ExprEncodingRef;
36
37 fn metadata(expr: &Self::Expr) -> Option<Self::Metadata>;
40
41 fn children(expr: &Self::Expr) -> Vec<&ExprRef>;
43
44 fn with_children(expr: &Self::Expr, children: Vec<ExprRef>) -> VortexResult<Self::Expr>;
50
51 fn build(
53 encoding: &Self::Encoding,
54 metadata: &<Self::Metadata as DeserializeMetadata>::Output,
55 children: Vec<ExprRef>,
56 ) -> VortexResult<Self::Expr>;
57
58 fn evaluate(expr: &Self::Expr, scope: &Scope) -> VortexResult<ArrayRef>;
60
61 fn return_dtype(expr: &Self::Expr, scope: &DType) -> VortexResult<DType>;
63}
64
65#[macro_export]
66macro_rules! vtable {
67 ($V:ident) => {
68 $crate::aliases::paste::paste! {
69 #[derive(Debug)]
70 pub struct [<$V VTable>];
71
72 impl AsRef<dyn $crate::VortexExpr> for [<$V Expr>] {
73 fn as_ref(&self) -> &dyn $crate::VortexExpr {
74 unsafe { &*(self as *const [<$V Expr>] as *const $crate::ExprAdapter<[<$V VTable>]>) }
76 }
77 }
78
79 impl std::ops::Deref for [<$V Expr>] {
80 type Target = dyn $crate::VortexExpr;
81
82 fn deref(&self) -> &Self::Target {
83 unsafe { &*(self as *const [<$V Expr>] as *const $crate::ExprAdapter<[<$V VTable>]>) }
85 }
86 }
87
88 impl $crate::IntoExpr for [<$V Expr>] {
89 fn into_expr(self) -> $crate::ExprRef {
90 std::sync::Arc::new(unsafe { std::mem::transmute::<[<$V Expr>], $crate::ExprAdapter::<[<$V VTable>]>>(self) })
92 }
93 }
94
95 impl AsRef<dyn $crate::ExprEncoding> for [<$V ExprEncoding>] {
96 fn as_ref(&self) -> &dyn $crate::ExprEncoding {
97 unsafe { &*(self as *const [<$V ExprEncoding>] as *const $crate::ExprEncodingAdapter<[<$V VTable>]>) }
99 }
100 }
101
102 impl std::ops::Deref for [<$V ExprEncoding>] {
103 type Target = dyn $crate::ExprEncoding;
104
105 fn deref(&self) -> &Self::Target {
106 unsafe { &*(self as *const [<$V ExprEncoding>] as *const $crate::ExprEncodingAdapter<[<$V VTable>]>) }
108 }
109 }
110 }
111 };
112}