vortex_expr/
encoding.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::any::Any;
5use std::fmt::{Debug, Display, Formatter};
6
7use arcref::ArcRef;
8use vortex_array::DeserializeMetadata;
9use vortex_error::{VortexExpect, VortexResult};
10
11use crate::{ExprRef, IntoExpr, VTable};
12
13pub type ExprId = ArcRef<str>;
14pub type ExprEncodingRef = ArcRef<dyn ExprEncoding>;
15
16/// Encoding trait for a Vortex expression.
17///
18/// An [`ExprEncoding`] can be registered with a Vortex session in order to support deserialization
19/// via the expression protobuf representation.
20pub trait ExprEncoding: 'static + Send + Sync + Debug + private::Sealed {
21    fn as_any(&self) -> &dyn Any;
22
23    /// Returns the ID of the expression encoding.
24    fn id(&self) -> ExprId;
25
26    /// Deserializes an expression from its serialized form.
27    ///
28    /// Returns `None` if the expression is not serializable.
29    fn build(&self, metadata: &[u8], children: Vec<ExprRef>) -> VortexResult<ExprRef>;
30}
31
32#[repr(transparent)]
33pub struct ExprEncodingAdapter<V: VTable>(V::Encoding);
34
35impl<V: VTable> ExprEncoding for ExprEncodingAdapter<V> {
36    fn as_any(&self) -> &dyn Any {
37        self
38    }
39
40    fn id(&self) -> ExprId {
41        V::id(&self.0)
42    }
43
44    fn build(&self, metadata: &[u8], children: Vec<ExprRef>) -> VortexResult<ExprRef> {
45        let metadata = <V::Metadata as DeserializeMetadata>::deserialize(metadata)?;
46        Ok(V::build(&self.0, &metadata, children)?.into_expr())
47    }
48}
49
50impl<V: VTable> Debug for ExprEncodingAdapter<V> {
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        f.debug_struct("ExprEncoding")
53            .field("id", &self.id())
54            .finish()
55    }
56}
57
58impl Display for dyn ExprEncoding + '_ {
59    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60        write!(f, "{}", self.id())
61    }
62}
63
64impl PartialEq for dyn ExprEncoding + '_ {
65    fn eq(&self, other: &Self) -> bool {
66        self.id() == other.id()
67    }
68}
69
70impl Eq for dyn ExprEncoding + '_ {}
71
72impl dyn ExprEncoding + '_ {
73    pub fn is<V: VTable>(&self) -> bool {
74        self.as_opt::<V>().is_some()
75    }
76
77    pub fn as_<V: VTable>(&self) -> &V::Encoding {
78        self.as_opt::<V>()
79            .vortex_expect("ExprEncoding is not of the expected type")
80    }
81
82    pub fn as_opt<V: VTable>(&self) -> Option<&V::Encoding> {
83        self.as_any()
84            .downcast_ref::<ExprEncodingAdapter<V>>()
85            .map(|e| &e.0)
86    }
87}
88
89mod private {
90    use super::*;
91
92    pub trait Sealed {}
93
94    impl<V: VTable> Sealed for ExprEncodingAdapter<V> {}
95}