arrow_schema/extension/canonical/
uuid.rs1use crate::{ArrowError, DataType, extension::ExtensionType};
23
24#[derive(Debug, Default, Clone, Copy, PartialEq)]
38pub struct Uuid;
39
40impl ExtensionType for Uuid {
41 const NAME: &'static str = "arrow.uuid";
42
43 type Metadata = ();
44
45 fn metadata(&self) -> &Self::Metadata {
46 &()
47 }
48
49 fn serialize_metadata(&self) -> Option<String> {
50 None
51 }
52
53 fn deserialize_metadata(metadata: Option<&str>) -> Result<Self::Metadata, ArrowError> {
54 metadata.map_or_else(
55 || Ok(()),
56 |v| {
57 if !v.is_empty() {
58 Err(ArrowError::InvalidArgumentError(
59 "Uuid extension type expects no metadata".to_owned(),
60 ))
61 } else {
62 Ok(())
63 }
64 },
65 )
66 }
67
68 fn supports_data_type(&self, data_type: &DataType) -> Result<(), ArrowError> {
69 match data_type {
70 DataType::FixedSizeBinary(16) => Ok(()),
71 data_type => Err(ArrowError::InvalidArgumentError(format!(
72 "Uuid data type mismatch, expected FixedSizeBinary(16), found {data_type}"
73 ))),
74 }
75 }
76
77 fn try_new(data_type: &DataType, _metadata: Self::Metadata) -> Result<Self, ArrowError> {
78 Self.supports_data_type(data_type).map(|_| Self)
79 }
80
81 fn validate(data_type: &DataType, _metadata: Self::Metadata) -> Result<(), ArrowError> {
82 Self.supports_data_type(data_type)
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 #[cfg(feature = "canonical_extension_types")]
89 use crate::extension::CanonicalExtensionType;
90 use crate::{
91 Field,
92 extension::{EXTENSION_TYPE_METADATA_KEY, EXTENSION_TYPE_NAME_KEY},
93 };
94
95 use super::*;
96
97 #[test]
98 fn valid() -> Result<(), ArrowError> {
99 let mut field = Field::new("", DataType::FixedSizeBinary(16), false);
100 field.try_with_extension_type(Uuid)?;
101 field.try_extension_type::<Uuid>()?;
102 #[cfg(feature = "canonical_extension_types")]
103 assert_eq!(
104 field.try_canonical_extension_type()?,
105 CanonicalExtensionType::Uuid(Uuid)
106 );
107 Ok(())
108 }
109
110 #[test]
111 #[should_panic(expected = "Extension type name missing")]
112 fn missing_name() {
113 let field = Field::new("", DataType::FixedSizeBinary(16), false);
114 field.extension_type::<Uuid>();
115 }
116
117 #[test]
118 #[should_panic(expected = "expected FixedSizeBinary(16), found FixedSizeBinary(8)")]
119 fn invalid_type() {
120 Field::new("", DataType::FixedSizeBinary(8), false).with_extension_type(Uuid);
121 }
122
123 #[test]
124 #[should_panic(expected = "Uuid extension type expects no metadata")]
125 fn with_metadata() {
126 let field = Field::new("", DataType::FixedSizeBinary(16), false).with_metadata(
127 [
128 (EXTENSION_TYPE_NAME_KEY.to_owned(), Uuid::NAME.to_owned()),
129 (
130 EXTENSION_TYPE_METADATA_KEY.to_owned(),
131 "unexpected".to_owned(),
132 ),
133 ]
134 .into_iter()
135 .collect(),
136 );
137 field.extension_type::<Uuid>();
138 }
139
140 #[test]
141 fn empty_metadata_string_is_treated_as_none() -> Result<(), ArrowError> {
142 let field = Field::new("", DataType::FixedSizeBinary(16), false).with_metadata(
143 [
144 (EXTENSION_TYPE_NAME_KEY.to_owned(), Uuid::NAME.to_owned()),
145 (EXTENSION_TYPE_METADATA_KEY.to_owned(), "".to_owned()),
146 ]
147 .into_iter()
148 .collect(),
149 );
150 field.try_extension_type::<Uuid>()?;
151 Ok(())
152 }
153}