arrow_schema/extension/canonical/
opaque.rs1use serde_core::ser::SerializeStruct;
10use serde_core::{
11 Deserialize, Deserializer, Serialize, Serializer,
12 de::{MapAccess, Visitor},
13};
14
15use crate::{ArrowError, DataType, extension::ExtensionType};
16
17#[derive(Debug, Clone, PartialEq)]
29pub struct Opaque(OpaqueMetadata);
30
31impl Opaque {
32 pub fn new(type_name: impl Into<String>, vendor_name: impl Into<String>) -> Self {
34 Self(OpaqueMetadata::new(type_name, vendor_name))
35 }
36
37 pub fn type_name(&self) -> &str {
39 self.0.type_name()
40 }
41
42 pub fn vendor_name(&self) -> &str {
44 self.0.vendor_name()
45 }
46}
47
48impl From<OpaqueMetadata> for Opaque {
49 fn from(value: OpaqueMetadata) -> Self {
50 Self(value)
51 }
52}
53
54#[derive(Debug, Clone, PartialEq)]
56pub struct OpaqueMetadata {
57 type_name: String,
59
60 vendor_name: String,
62}
63
64impl Serialize for OpaqueMetadata {
65 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66 where
67 S: Serializer,
68 {
69 let mut state = serializer.serialize_struct("OpaqueMetadata", 2)?;
70 state.serialize_field("type_name", &self.type_name)?;
71 state.serialize_field("vendor_name", &self.vendor_name)?;
72 state.end()
73 }
74}
75
76#[derive(Debug)]
77enum MetadataField {
78 TypeName,
79 VendorName,
80}
81
82struct MetadataFieldVisitor;
83
84impl Visitor<'_> for MetadataFieldVisitor {
85 type Value = MetadataField;
86
87 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
88 formatter.write_str("`type_name` or `vendor_name`")
89 }
90
91 fn visit_str<E>(self, value: &str) -> Result<MetadataField, E>
92 where
93 E: serde_core::de::Error,
94 {
95 match value {
96 "type_name" => Ok(MetadataField::TypeName),
97 "vendor_name" => Ok(MetadataField::VendorName),
98 _ => Err(serde_core::de::Error::unknown_field(
99 value,
100 &["type_name", "vendor_name"],
101 )),
102 }
103 }
104}
105
106impl<'de> Deserialize<'de> for MetadataField {
107 fn deserialize<D>(deserializer: D) -> Result<MetadataField, D::Error>
108 where
109 D: Deserializer<'de>,
110 {
111 deserializer.deserialize_identifier(MetadataFieldVisitor)
112 }
113}
114
115struct OpaqueMetadataVisitor;
116
117impl<'de> Visitor<'de> for OpaqueMetadataVisitor {
118 type Value = OpaqueMetadata;
119
120 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
121 formatter.write_str("struct OpaqueMetadata")
122 }
123
124 fn visit_seq<V>(self, mut seq: V) -> Result<OpaqueMetadata, V::Error>
125 where
126 V: serde_core::de::SeqAccess<'de>,
127 {
128 let type_name = seq
129 .next_element()?
130 .ok_or_else(|| serde_core::de::Error::invalid_length(0, &self))?;
131 let vendor_name = seq
132 .next_element()?
133 .ok_or_else(|| serde_core::de::Error::invalid_length(1, &self))?;
134 Ok(OpaqueMetadata {
135 type_name,
136 vendor_name,
137 })
138 }
139
140 fn visit_map<V>(self, mut map: V) -> Result<OpaqueMetadata, V::Error>
141 where
142 V: MapAccess<'de>,
143 {
144 let mut type_name = None;
145 let mut vendor_name = None;
146
147 while let Some(key) = map.next_key()? {
148 match key {
149 MetadataField::TypeName => {
150 if type_name.is_some() {
151 return Err(serde_core::de::Error::duplicate_field("type_name"));
152 }
153 type_name = Some(map.next_value()?);
154 }
155 MetadataField::VendorName => {
156 if vendor_name.is_some() {
157 return Err(serde_core::de::Error::duplicate_field("vendor_name"));
158 }
159 vendor_name = Some(map.next_value()?);
160 }
161 }
162 }
163
164 let type_name =
165 type_name.ok_or_else(|| serde_core::de::Error::missing_field("type_name"))?;
166 let vendor_name =
167 vendor_name.ok_or_else(|| serde_core::de::Error::missing_field("vendor_name"))?;
168
169 Ok(OpaqueMetadata {
170 type_name,
171 vendor_name,
172 })
173 }
174}
175
176impl<'de> Deserialize<'de> for OpaqueMetadata {
177 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
178 where
179 D: Deserializer<'de>,
180 {
181 deserializer.deserialize_struct(
182 "OpaqueMetadata",
183 &["type_name", "vendor_name"],
184 OpaqueMetadataVisitor,
185 )
186 }
187}
188
189impl OpaqueMetadata {
190 pub fn new(type_name: impl Into<String>, vendor_name: impl Into<String>) -> Self {
192 OpaqueMetadata {
193 type_name: type_name.into(),
194 vendor_name: vendor_name.into(),
195 }
196 }
197
198 pub fn type_name(&self) -> &str {
200 &self.type_name
201 }
202
203 pub fn vendor_name(&self) -> &str {
205 &self.vendor_name
206 }
207}
208
209impl ExtensionType for Opaque {
210 const NAME: &'static str = "arrow.opaque";
211
212 type Metadata = OpaqueMetadata;
213
214 fn metadata(&self) -> &Self::Metadata {
215 &self.0
216 }
217
218 fn serialize_metadata(&self) -> Option<String> {
219 Some(serde_json::to_string(self.metadata()).expect("metadata serialization"))
220 }
221
222 fn deserialize_metadata(metadata: Option<&str>) -> Result<Self::Metadata, ArrowError> {
223 metadata.map_or_else(
224 || {
225 Err(ArrowError::InvalidArgumentError(
226 "Opaque extension types requires metadata".to_owned(),
227 ))
228 },
229 |value| {
230 serde_json::from_str(value).map_err(|e| {
231 ArrowError::InvalidArgumentError(format!(
232 "Opaque metadata deserialization failed: {e}"
233 ))
234 })
235 },
236 )
237 }
238
239 fn supports_data_type(&self, _data_type: &DataType) -> Result<(), ArrowError> {
240 Ok(())
242 }
243
244 fn try_new(_data_type: &DataType, metadata: Self::Metadata) -> Result<Self, ArrowError> {
245 Ok(Self::from(metadata))
246 }
247
248 fn validate(_data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> {
249 Ok(())
250 }
251}
252
253#[cfg(test)]
254mod tests {
255 #[cfg(feature = "canonical_extension_types")]
256 use crate::extension::CanonicalExtensionType;
257 use crate::{
258 Field,
259 extension::{EXTENSION_TYPE_METADATA_KEY, EXTENSION_TYPE_NAME_KEY},
260 };
261
262 use super::*;
263
264 #[test]
265 fn valid() -> Result<(), ArrowError> {
266 let opaque = Opaque::new("name", "vendor");
267 let mut field = Field::new("", DataType::Null, false);
268 field.try_with_extension_type(opaque.clone())?;
269 assert_eq!(field.try_extension_type::<Opaque>()?, opaque);
270 #[cfg(feature = "canonical_extension_types")]
271 assert_eq!(
272 field.try_canonical_extension_type()?,
273 CanonicalExtensionType::Opaque(opaque)
274 );
275 Ok(())
276 }
277
278 #[test]
279 #[should_panic(expected = "Extension type name missing")]
280 fn missing_name() {
281 let field = Field::new("", DataType::Null, false).with_metadata([(
282 EXTENSION_TYPE_METADATA_KEY,
283 r#"{ "type_name": "type", "vendor_name": "vendor" }"#,
284 )]);
285 field.extension_type::<Opaque>();
286 }
287
288 #[test]
289 #[should_panic(expected = "Opaque extension types requires metadata")]
290 fn missing_metadata() {
291 let field = Field::new("", DataType::Null, false)
292 .with_metadata([(EXTENSION_TYPE_NAME_KEY, Opaque::NAME)]);
293 field.extension_type::<Opaque>();
294 }
295
296 #[test]
297 #[should_panic(
298 expected = "Opaque metadata deserialization failed: missing field `vendor_name`"
299 )]
300 fn invalid_metadata() {
301 let field = Field::new("", DataType::Null, false).with_metadata([
302 (EXTENSION_TYPE_NAME_KEY, Opaque::NAME),
303 (
304 EXTENSION_TYPE_METADATA_KEY,
305 r#"{ "type_name": "no-vendor" }"#,
306 ),
307 ]);
308 field.extension_type::<Opaque>();
309 }
310}