vortex_dtype/
extension.rs1use std::fmt::{Display, Formatter};
2use std::sync::Arc;
3
4use crate::{DType, Nullability};
5
6#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
8#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
9pub struct ExtID(Arc<str>);
10
11impl ExtID {
12 pub fn new(value: Arc<str>) -> Self {
14 Self(value)
15 }
16}
17
18impl Display for ExtID {
19 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20 write!(f, "{}", self.0)
21 }
22}
23
24impl AsRef<str> for ExtID {
25 fn as_ref(&self) -> &str {
26 self.0.as_ref()
27 }
28}
29
30impl From<&str> for ExtID {
31 fn from(value: &str) -> Self {
32 Self(value.into())
33 }
34}
35
36#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Hash)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct ExtMetadata(Arc<[u8]>);
40
41impl ExtMetadata {
42 pub fn new(value: Arc<[u8]>) -> Self {
44 Self(value)
45 }
46}
47
48impl AsRef<[u8]> for ExtMetadata {
49 fn as_ref(&self) -> &[u8] {
50 self.0.as_ref()
51 }
52}
53
54impl From<&[u8]> for ExtMetadata {
55 fn from(value: &[u8]) -> Self {
56 Self(value.into())
57 }
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Hash)]
62#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
63pub struct ExtDType {
64 id: ExtID,
65 storage_dtype: Arc<DType>,
66 metadata: Option<ExtMetadata>,
67}
68
69impl ExtDType {
70 pub fn new(id: ExtID, storage_dtype: Arc<DType>, metadata: Option<ExtMetadata>) -> Self {
101 assert!(
102 !matches!(storage_dtype.as_ref(), &DType::Extension(_)),
103 "ExtDType cannot have Extension storage_dtype"
104 );
105
106 Self {
107 id,
108 storage_dtype,
109 metadata,
110 }
111 }
112
113 #[inline]
115 pub fn id(&self) -> &ExtID {
116 &self.id
117 }
118
119 #[inline]
121 pub fn storage_dtype(&self) -> &DType {
122 self.storage_dtype.as_ref()
123 }
124
125 pub fn with_nullability(&self, nullability: Nullability) -> Self {
127 Self::new(
128 self.id.clone(),
129 Arc::new(self.storage_dtype.with_nullability(nullability)),
130 self.metadata.clone(),
131 )
132 }
133
134 #[inline]
136 pub fn metadata(&self) -> Option<&ExtMetadata> {
137 self.metadata.as_ref()
138 }
139
140 pub fn eq_ignore_nullability(&self, other: &Self) -> bool {
142 self.id() == other.id()
143 && self.metadata() == other.metadata()
144 && self
145 .storage_dtype()
146 .eq_ignore_nullability(other.storage_dtype())
147 }
148}
149
150#[cfg(test)]
151mod test {
152 use std::sync::Arc;
153
154 use super::{ExtDType, ExtID};
155 use crate::{DType, Nullability, PType};
156
157 #[test]
158 fn different_ids_are_not_equal() {
159 let storage_dtype = Arc::from(DType::Bool(Nullability::NonNullable));
160 let one = ExtDType::new(ExtID::new(Arc::from("one")), storage_dtype.clone(), None);
161 let two = ExtDType::new(ExtID::new(Arc::from("two")), storage_dtype, None);
162
163 assert_ne!(one, two);
164 }
165
166 #[test]
167 fn same_id_different_storage_types_are_not_equal() {
168 let one = ExtDType::new(
169 ExtID::new(Arc::from("one")),
170 Arc::from(DType::Bool(Nullability::NonNullable)),
171 None,
172 );
173 let two = ExtDType::new(
174 ExtID::new(Arc::from("one")),
175 Arc::from(DType::Primitive(PType::U8, Nullability::NonNullable)),
176 None,
177 );
178
179 assert_ne!(one, two);
180 }
181
182 #[test]
183 fn same_id_different_nullability_are_not_equal() {
184 let nullable_u8 = Arc::from(DType::Primitive(PType::U8, Nullability::NonNullable));
185 let one = ExtDType::new(ExtID::new(Arc::from("one")), nullable_u8.clone(), None);
186 let two = ExtDType::new(
187 ExtID::new(Arc::from("one")),
188 Arc::from(nullable_u8.as_nullable()),
189 None,
190 );
191
192 assert_ne!(one, two);
193 }
194}