Skip to content

Commit

Permalink
Add arrow-array support for Field
Browse files Browse the repository at this point in the history
  • Loading branch information
HoKim98 committed Oct 23, 2023
1 parent 5c558a0 commit b9e285d
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
5 changes: 4 additions & 1 deletion crates/grafana-plugin-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ repository = "https://github.com/grafana/grafana-plugin-sdk-rust"
description = "SDK for building Grafana backend plugins."

[dependencies]
arrow2 = { version = "0.17.0", features = ["io_ipc"] }
arrow-array = { version = ">=40", optional = true } # synced with arrow2
arrow-schema = { version = ">=40", optional = true } # synced with arrow2
arrow2 = { version = "0.18.0", features = ["io_ipc"] }
cfg-if = "1.0.0"
chrono = "0.4.19"
futures-core = "0.3.17"
Expand Down Expand Up @@ -61,6 +63,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
arrow = ["dep:arrow-array", "dep:arrow-schema", "arrow2/arrow"]
reqwest = ["reqwest_lib"]
# Since prost 0.11 we no longer use prost-build at build time to generate code,
# because it requires protoc. The generated code is instead checked in to source
Expand Down
71 changes: 71 additions & 0 deletions crates/grafana-plugin-sdk/src/data/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,32 @@ where
}
}

/// Helper trait for creating a [`Field`] from an [`Array`][arrow_array::Array].
pub trait ArrayRefIntoField {
/// Create a `Field` using `self` as the values.
///
/// # Errors
///
/// This returns an error if the values are not valid field types.
fn try_into_field(self, name: impl Into<String>) -> Result<Field, error::Error>;
}

#[cfg(feature = "arrow")]
impl ArrayRefIntoField for &dyn ::arrow_array::Array {
fn try_into_field(self, name: impl Into<String>) -> Result<Field, error::Error> {
Ok(Field {
name: name.into(),
labels: Default::default(),
config: None,
type_info: TypeInfo {
frame: self.data_type().try_into()?,
nullable: Some(true),
},
values: self.into(),
})
}
}

/// The type information for a [`Frame`][crate::data::Frame] as understood by Grafana.
#[skip_serializing_none]
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
Expand Down Expand Up @@ -496,6 +522,51 @@ impl From<TypeInfoType> for DataType {
}
}

#[cfg(feature = "arrow")]
impl TryFrom<&::arrow_schema::DataType> for TypeInfoType {
type Error = error::Error;
fn try_from(other: &::arrow_schema::DataType) -> Result<Self, Self::Error> {
Ok(match other {
::arrow_schema::DataType::Int8 => Self::Int8,
::arrow_schema::DataType::Int16 => Self::Int16,
::arrow_schema::DataType::Int32 => Self::Int32,
::arrow_schema::DataType::Int64 => Self::Int64,
::arrow_schema::DataType::UInt8 => Self::UInt8,
::arrow_schema::DataType::UInt16 => Self::UInt16,
::arrow_schema::DataType::UInt32 => Self::UInt32,
::arrow_schema::DataType::UInt64 => Self::UInt64,
::arrow_schema::DataType::Float32 => Self::Float32,
::arrow_schema::DataType::Float64 => Self::Float64,
::arrow_schema::DataType::Utf8 => Self::String,
::arrow_schema::DataType::Boolean => Self::Bool,
::arrow_schema::DataType::Timestamp(..) => Self::Time,
// TODO - handle time correctly.
other => return Err(error::Error::UnsupportedArrowDataType(other.clone().into())),
})
}
}

#[cfg(feature = "arrow")]
impl From<TypeInfoType> for ::arrow_schema::DataType {
fn from(other: TypeInfoType) -> Self {
match other {
TypeInfoType::Int8 => Self::Int8,
TypeInfoType::Int16 => Self::Int16,
TypeInfoType::Int32 => Self::Int32,
TypeInfoType::Int64 => Self::Int64,
TypeInfoType::UInt8 => Self::UInt8,
TypeInfoType::UInt16 => Self::UInt16,
TypeInfoType::UInt32 => Self::UInt32,
TypeInfoType::UInt64 => Self::UInt64,
TypeInfoType::Float32 => Self::Float32,
TypeInfoType::Float64 => Self::Float64,
TypeInfoType::String => Self::Utf8,
TypeInfoType::Bool => Self::Boolean,
TypeInfoType::Time => Self::Timestamp(::arrow_schema::TimeUnit::Nanosecond, None),
}
}
}

impl TypeInfoType {
#[must_use]
pub(crate) const fn simple_type(&self) -> SimpleType {
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.57.0"
channel = "1.62.0"
components = ["rustfmt", "clippy"]

0 comments on commit b9e285d

Please sign in to comment.