use std::sync::Arc;
use arrow::array::{Array as _, ArrayRef};
use crate::{ArchetypeName, ComponentName};
pub trait Enum:
Sized + Copy + Clone + std::hash::Hash + PartialEq + Eq + std::fmt::Display + 'static
{
fn variants() -> &'static [Self];
fn docstring_md(self) -> &'static str;
}
#[derive(Clone, Debug, Default)]
pub struct Reflection {
pub components: ComponentReflectionMap,
pub archetypes: ArchetypeReflectionMap,
}
impl Reflection {
pub fn archetype_reflection_from_short_name(
&self,
short_name: &str,
) -> Option<&ArchetypeReflection> {
self.archetypes
.get(&ArchetypeName::from(short_name))
.or_else(|| {
self.archetypes.get(&ArchetypeName::from(format!(
"rerun.archetypes.{short_name}"
)))
})
.or_else(|| {
self.archetypes.get(&ArchetypeName::from(format!(
"rerun.blueprint.archetypes.{short_name}"
)))
})
.or_else(|| {
self.archetypes
.get(&ArchetypeName::from(format!("rerun.{short_name}")))
})
}
}
pub fn generic_placeholder_for_datatype(
datatype: &arrow::datatypes::DataType,
) -> arrow::array::ArrayRef {
use arrow::{
array::{self, types},
datatypes::{DataType, IntervalUnit},
};
match datatype {
DataType::Null => Arc::new(array::NullArray::new(1)),
DataType::Boolean => Arc::new(array::BooleanArray::from_iter([Some(false)])),
DataType::Int8 => Arc::new(array::Int8Array::from_iter([0])),
DataType::Int16 => Arc::new(array::Int16Array::from_iter([0])),
DataType::Int32
| DataType::Date32
| DataType::Time32(_)
| DataType::Interval(IntervalUnit::YearMonth) => {
Arc::new(array::Int32Array::from_iter([0]))
}
DataType::Int64
| DataType::Date64
| DataType::Timestamp(_, _)
| DataType::Time64(_)
| DataType::Duration(_) => {
Arc::new(array::Int64Array::from_iter([0]))
}
DataType::UInt8 => Arc::new(array::UInt8Array::from_iter([0])),
DataType::UInt16 => Arc::new(array::UInt16Array::from_iter([0])),
DataType::UInt32 => Arc::new(array::UInt32Array::from_iter([0])),
DataType::UInt64 => Arc::new(array::UInt64Array::from_iter([0])),
DataType::Float16 => Arc::new(array::Float16Array::from_iter([half::f16::ZERO])),
DataType::Float32 => Arc::new(array::Float32Array::from_iter([0.0])),
DataType::Float64 => Arc::new(array::Float64Array::from_iter([0.0])),
DataType::Interval(IntervalUnit::DayTime) => {
Arc::new(array::IntervalDayTimeArray::from(vec![
types::IntervalDayTime::new(0, 0),
]))
}
DataType::Interval(IntervalUnit::MonthDayNano) => {
Arc::new(array::IntervalMonthDayNanoArray::from(vec![
types::IntervalMonthDayNano::new(0, 0, 0),
]))
}
DataType::Binary => Arc::new(array::GenericBinaryArray::<i32>::from_vec(vec![&[]])),
DataType::LargeBinary => Arc::new(array::GenericBinaryArray::<i64>::from_vec(vec![&[]])),
DataType::Utf8 => Arc::new(array::StringArray::from(vec![""])),
DataType::LargeUtf8 => Arc::new(array::LargeStringArray::from(vec![""])),
DataType::List(field) => {
let inner = generic_placeholder_for_datatype(field.data_type());
let offsets = arrow::buffer::OffsetBuffer::from_lengths(std::iter::once(inner.len()));
Arc::new(array::GenericListArray::<i32>::new(
field.clone(),
offsets,
inner,
None,
))
}
DataType::FixedSizeList(field, size) => {
let size = *size as usize;
let value_data: ArrayRef = {
match field.data_type() {
DataType::Boolean => Arc::new(array::BooleanArray::from(vec![false; size])),
DataType::Int8 => Arc::new(array::Int8Array::from(vec![0; size])),
DataType::Int16 => Arc::new(array::Int16Array::from(vec![0; size])),
DataType::Int32 => Arc::new(array::Int32Array::from(vec![0; size])),
DataType::Int64 => Arc::new(array::Int64Array::from(vec![0; size])),
DataType::UInt8 => Arc::new(array::UInt8Array::from(vec![0; size])),
DataType::UInt16 => Arc::new(array::UInt16Array::from(vec![0; size])),
DataType::UInt32 => Arc::new(array::UInt32Array::from(vec![0; size])),
DataType::UInt64 => Arc::new(array::UInt64Array::from(vec![0; size])),
DataType::Float16 => {
Arc::new(array::Float16Array::from(vec![half::f16::ZERO; size]))
}
DataType::Float32 => Arc::new(array::Float32Array::from(vec![0.0; size])),
DataType::Float64 => Arc::new(array::Float64Array::from(vec![0.0; size])),
_ => {
re_log::debug_once!(
"Unimplemented: placeholder value for FixedSizeListArray of {:?}",
field.data_type()
);
return array::new_empty_array(datatype);
}
}
};
if let Ok(list_data) = array::ArrayData::builder(datatype.clone())
.len(1)
.add_child_data(value_data.into_data())
.build()
{
Arc::new(array::FixedSizeListArray::from(list_data))
} else {
re_log::warn_once!("Bug in FixedSizeListArray of {:?}", field.data_type());
array::new_empty_array(datatype)
}
}
DataType::LargeList(field) => {
let inner = generic_placeholder_for_datatype(field.data_type());
let offsets = arrow::buffer::OffsetBuffer::from_lengths(std::iter::once(inner.len()));
Arc::new(array::GenericListArray::<i64>::new(
field.clone(),
offsets,
inner,
None,
))
}
DataType::Struct(fields) => {
let inners = fields
.iter()
.map(|field| generic_placeholder_for_datatype(field.data_type()));
Arc::new(array::StructArray::new(
fields.clone(),
inners.collect(),
None,
))
}
DataType::Decimal128(_, _) => Arc::new(array::Decimal128Array::from_iter([0])),
DataType::Decimal256(_, _) => Arc::new(array::Decimal256Array::from_iter([
arrow::datatypes::i256::ZERO,
])),
DataType::FixedSizeBinary { .. }
| DataType::Dictionary { .. }
| DataType::Union { .. }
| DataType::Map { .. }
| DataType::BinaryView
| DataType::Utf8View
| DataType::ListView { .. }
| DataType::LargeListView { .. }
| DataType::RunEndEncoded { .. } => {
re_log::debug_once!("Unimplemented: placeholder value for: {datatype:?}");
array::new_empty_array(datatype) }
}
}
pub type ComponentReflectionMap = nohash_hasher::IntMap<ComponentName, ComponentReflection>;
#[derive(Clone, Debug)]
pub struct ComponentReflection {
pub docstring_md: &'static str,
pub deprecation_summary: Option<&'static str>,
pub custom_placeholder: Option<ArrayRef>,
pub datatype: arrow::datatypes::DataType,
pub verify_arrow_array: fn(&dyn arrow::array::Array) -> crate::DeserializationResult<()>,
}
pub type ArchetypeReflectionMap = nohash_hasher::IntMap<ArchetypeName, ArchetypeReflection>;
#[derive(Clone, Debug)]
pub struct ArchetypeReflection {
pub display_name: &'static str,
pub deprecation_summary: Option<&'static str>,
pub view_types: &'static [&'static str],
pub scope: Option<&'static str>,
pub fields: Vec<ArchetypeFieldReflection>,
}
impl ArchetypeReflection {
#[inline]
pub fn required_fields(&self) -> impl Iterator<Item = &ArchetypeFieldReflection> {
self.fields.iter().filter(|field| field.is_required)
}
pub fn get_field(&self, field_name: &str) -> Option<&ArchetypeFieldReflection> {
self.fields.iter().find(|field| field.name == field_name)
}
}
#[derive(Clone, Debug)]
pub struct ArchetypeFieldReflection {
pub name: &'static str,
pub display_name: &'static str,
pub component_name: ComponentName,
pub docstring_md: &'static str,
pub is_required: bool,
}