use std::collections::HashMap;
use arrow_schema::{DataType, Field};
#[derive(Debug, PartialEq)]
pub struct ExtensionType {
pub extension_name: String,
pub storage_type: DataType,
pub extension_metadata: Option<String>,
}
impl ExtensionType {
pub fn new(ext_name: &str, storage_type: DataType, extension_metadata: Option<String>) -> Self {
let extension_name = ext_name.to_string();
Self {
extension_name,
storage_type,
extension_metadata,
}
}
pub fn to_field(&self, name: &str, nullable: bool) -> Field {
let mut field = Field::new(name, self.storage_type.clone(), nullable);
let mut metadata = HashMap::from([(
"ARROW:extension:name".to_string(),
self.extension_name.clone(),
)]);
if let Some(extension_metadata) = &self.extension_metadata {
metadata.insert(
"ARROW:extension:metadata".to_string(),
extension_metadata.clone(),
);
}
field.set_metadata(metadata);
field
}
pub fn from_field(field: &Field) -> Option<ExtensionType> {
let metadata = field.metadata();
metadata.get("ARROW:extension:name").map(|extension_name| {
ExtensionType::new(
extension_name,
field.data_type().clone(),
metadata.get("ARROW:extension:metadata").cloned(),
)
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extension_type_field() {
let ext_type = ExtensionType::new("foofy", DataType::Binary, None);
let field = ext_type.to_field("some name", true);
assert_eq!(field.name(), "some name");
assert_eq!(*field.data_type(), DataType::Binary);
let metadata = field.metadata();
assert_eq!(metadata.len(), 1);
assert!(metadata.contains_key("ARROW:extension:name"));
assert_eq!(metadata["ARROW:extension:name"], "foofy");
}
#[test]
fn extension_type_field_with_metadata() {
let ext_type = ExtensionType::new(
"foofy",
DataType::Binary,
Some("foofy metadata".to_string()),
);
let field = ext_type.to_field("some name", true);
let metadata = field.metadata();
assert_eq!(metadata.len(), 2);
assert!(metadata.contains_key("ARROW:extension:name"));
assert_eq!(metadata["ARROW:extension:name"], "foofy");
assert!(metadata.contains_key("ARROW:extension:metadata"));
assert_eq!(metadata["ARROW:extension:metadata"], "foofy metadata");
}
}