vortex_array/scalar/extension/
erased.rs1use std::any::type_name;
5use std::cmp::Ordering;
6use std::fmt;
7use std::hash::Hash;
8use std::hash::Hasher;
9use std::sync::Arc;
10
11use vortex_error::VortexExpect;
12use vortex_error::vortex_err;
13
14use crate::dtype::extension::ExtId;
15use crate::dtype::extension::ExtVTable;
16use crate::scalar::ScalarValue;
17use crate::scalar::extension::ExtScalarValue;
18use crate::scalar::extension::typed::DynExtScalarValue;
19use crate::scalar::extension::typed::ExtScalarValueInner;
20
21#[derive(Clone)]
34pub struct ExtScalarValueRef(pub(super) Arc<dyn DynExtScalarValue>);
35
36impl ExtScalarValueRef {
40 pub fn id(&self) -> ExtId {
42 self.0.id()
43 }
44
45 pub fn storage_value(&self) -> &ScalarValue {
47 self.0.storage_value()
48 }
49
50 pub fn try_downcast<V: ExtVTable>(self) -> Result<ExtScalarValue<V>, ExtScalarValueRef> {
56 if !self.0.as_any().is::<ExtScalarValueInner<V>>() {
60 return Err(self);
61 }
62
63 let ptr = Arc::into_raw(self.0) as *const ExtScalarValueInner<V>;
64 let inner = unsafe { Arc::from_raw(ptr) };
66
67 Ok(ExtScalarValue(inner))
68 }
69
70 pub fn downcast<V: ExtVTable>(self) -> ExtScalarValue<V> {
76 self.try_downcast::<V>()
77 .map_err(|this| {
78 vortex_err!(
79 "Failed to downcast ExtScalar {} to {}",
80 this.0.id(),
81 type_name::<V>(),
82 )
83 })
84 .vortex_expect("Failed to downcast ExtScalar")
85 }
86}
87
88impl fmt::Display for ExtScalarValueRef {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "{}({})", self.0.id(), self.0.storage_value())
91 }
92}
93
94impl fmt::Debug for ExtScalarValueRef {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 f.debug_struct("ExtScalar")
97 .field("id", &self.0.id())
98 .field("storage_value", self.0.storage_value())
99 .finish()
100 }
101}
102
103impl PartialEq for ExtScalarValueRef {
106 fn eq(&self, other: &Self) -> bool {
107 self.0.id() == other.0.id() && self.0.storage_value() == other.0.storage_value()
108 }
109}
110impl Eq for ExtScalarValueRef {}
111
112impl PartialOrd for ExtScalarValueRef {
113 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
114 self.0.storage_value().partial_cmp(other.0.storage_value())
116 }
117}
118
119impl Hash for ExtScalarValueRef {
120 fn hash<H: Hasher>(&self, state: &mut H) {
121 self.0.id().hash(state);
122 self.0.storage_value().hash(state);
123 }
124}