Skip to main content

vortex_array/scalar_fn/
plugin.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::any::Any;
5use std::fmt::Debug;
6use std::fmt::Display;
7use std::fmt::Formatter;
8use std::hash::Hash;
9use std::hash::Hasher;
10
11use arcref::ArcRef;
12use vortex_error::VortexResult;
13use vortex_session::VortexSession;
14
15use crate::scalar_fn::ScalarFnId;
16use crate::scalar_fn::ScalarFnRef;
17use crate::scalar_fn::ScalarFnVTable;
18use crate::scalar_fn::typed::DynScalarFnVTable;
19use crate::scalar_fn::typed::ScalarFnVTableAdapter;
20
21/// A Vortex scalar function vtable plugin, used to deserialize or instantiate scalar functions
22/// dynamically.
23#[derive(Clone)]
24pub struct ScalarFnPlugin(ArcRef<dyn DynScalarFnVTable>);
25
26impl ScalarFnPlugin {
27    /// Creates a new [`ScalarFnPlugin`] from a vtable.
28    pub fn new<V: ScalarFnVTable>(vtable: V) -> Self {
29        Self(ArcRef::new_arc(std::sync::Arc::new(ScalarFnVTableAdapter(
30            vtable,
31        ))))
32    }
33
34    /// Creates a new [`ScalarFnPlugin`] from a static reference to a vtable.
35    pub const fn new_static<V: ScalarFnVTable>(vtable: &'static V) -> Self {
36        // SAFETY: We can safely cast the vtable to a ScalarFnVTableAdapter since it has the same
37        // layout (#[repr(transparent)]).
38        let adapted: &'static ScalarFnVTableAdapter<V> =
39            unsafe { &*(vtable as *const V as *const ScalarFnVTableAdapter<V>) };
40        Self(ArcRef::new_ref(adapted as &'static dyn DynScalarFnVTable))
41    }
42
43    /// Returns the ID of this vtable.
44    pub fn id(&self) -> ScalarFnId {
45        self.0.id()
46    }
47
48    /// Returns whether this vtable is of a given type.
49    pub fn is<V: ScalarFnVTable>(&self) -> bool {
50        self.0.as_any().is::<V>()
51    }
52
53    /// Return the vtable as an Any reference.
54    pub fn as_any(&self) -> &dyn Any {
55        self.0.as_any()
56    }
57
58    /// Deserialize options of this scalar function vtable from metadata, returning a bound
59    /// [`ScalarFnRef`].
60    pub fn deserialize(
61        &self,
62        metadata: &[u8],
63        session: &VortexSession,
64    ) -> VortexResult<ScalarFnRef> {
65        let options = self.0.options_deserialize(metadata, session)?;
66        Ok(self.0.bind_deserialized(options))
67    }
68}
69
70impl PartialEq for ScalarFnPlugin {
71    fn eq(&self, other: &Self) -> bool {
72        self.0.id() == other.0.id()
73    }
74}
75impl Eq for ScalarFnPlugin {}
76
77impl Hash for ScalarFnPlugin {
78    fn hash<H: Hasher>(&self, state: &mut H) {
79        self.0.id().hash(state);
80    }
81}
82
83impl Display for ScalarFnPlugin {
84    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85        write!(f, "{}", self.0.id())
86    }
87}
88
89impl Debug for ScalarFnPlugin {
90    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
91        write!(f, "{}", self.0.id())
92    }
93}