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