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: &arrow2::datatypes::DataType,
) -> Box<dyn arrow2::array::Array> {
use arrow2::{
array,
datatypes::{DataType, IntervalUnit},
types,
};
match datatype {
DataType::Null => Box::new(array::NullArray::new(datatype.clone(), 1)),
DataType::Boolean => Box::new(array::BooleanArray::from_slice([false])),
DataType::Int8 => Box::new(array::Int8Array::from_slice([0])),
DataType::Int16 => Box::new(array::Int16Array::from_slice([0])),
DataType::Int32
| DataType::Date32
| DataType::Time32(_)
| DataType::Interval(IntervalUnit::YearMonth) => {
Box::new(array::Int32Array::from_slice([0]))
}
DataType::Int64
| DataType::Date64
| DataType::Timestamp(_, _)
| DataType::Time64(_)
| DataType::Duration(_) => {
Box::new(array::Int64Array::from_slice([0]))
}
DataType::UInt8 => Box::new(array::UInt8Array::from_slice([0])),
DataType::UInt16 => Box::new(array::UInt16Array::from_slice([0])),
DataType::UInt32 => Box::new(array::UInt32Array::from_slice([0])),
DataType::UInt64 => Box::new(array::UInt64Array::from_slice([0])),
DataType::Float16 => Box::new(array::Float16Array::from_slice([types::f16::from_f32(0.0)])),
DataType::Float32 => Box::new(array::Float32Array::from_slice([0.0])),
DataType::Float64 => Box::new(array::Float64Array::from_slice([0.0])),
DataType::Interval(IntervalUnit::DayTime) => {
Box::new(array::DaysMsArray::from_slice([types::days_ms::new(0, 0)]))
}
DataType::Interval(IntervalUnit::MonthDayNano) => {
Box::new(array::MonthsDaysNsArray::from_slice([
types::months_days_ns::new(0, 0, 0),
]))
}
DataType::Binary => Box::new(array::BinaryArray::<i32>::from_slice([[]])),
DataType::FixedSizeBinary(size) => Box::new(array::FixedSizeBinaryArray::from_iter(
std::iter::once(Some(vec![0; *size])),
*size,
)),
DataType::LargeBinary => Box::new(array::BinaryArray::<i64>::from_slice([[]])),
DataType::Utf8 => Box::new(array::Utf8Array::<i32>::from_slice([""])),
DataType::LargeUtf8 => Box::new(array::Utf8Array::<i64>::from_slice([""])),
DataType::List(field) => {
let inner = generic_placeholder_for_datatype(field.data_type());
let offsets = arrow2::offset::Offsets::try_from_lengths(std::iter::once(inner.len()))
.expect("failed to create offsets buffer");
Box::new(array::ListArray::<i32>::new(
datatype.clone(),
offsets.into(),
inner,
None,
))
}
DataType::FixedSizeList(_field, size) => {
Box::new(array::FixedSizeListArray::new_null(datatype.clone(), *size))
}
DataType::LargeList(field) => {
let inner = generic_placeholder_for_datatype(field.data_type());
let offsets = arrow2::offset::Offsets::try_from_lengths(std::iter::once(inner.len()))
.expect("failed to create offsets buffer");
Box::new(array::ListArray::<i64>::new(
datatype.clone(),
offsets.into(),
inner,
None,
))
}
DataType::Struct(fields) => {
let inners = fields
.iter()
.map(|field| generic_placeholder_for_datatype(field.data_type()));
Box::new(array::StructArray::new(
datatype.clone(),
inners.collect(),
None,
))
}
DataType::Union(fields, _types, _union_mode) => {
if let Some(first_field) = fields.first() {
let first_field = generic_placeholder_for_datatype(first_field.data_type());
let first_field_len = first_field.len(); let other_fields = fields
.iter()
.skip(1)
.map(|field| array::new_empty_array(field.data_type().clone()));
let fields = std::iter::once(first_field).chain(other_fields);
Box::new(array::UnionArray::new(
datatype.clone(),
std::iter::once(0).collect(), fields.collect(),
Some(std::iter::once(first_field_len as i32).collect()),
))
} else {
array::new_empty_array(datatype.clone())
}
}
DataType::Map(_field, _) => Box::new(array::MapArray::new_empty(datatype.clone())),
DataType::Dictionary(_integer_type, _arc, _sorted) => {
array::new_empty_array(datatype.clone()) }
DataType::Decimal(_, _) => Box::new(array::Int128Array::from_slice([0])),
DataType::Decimal256(_, _) => {
Box::new(array::Int256Array::from_slice([types::i256::from_words(
0, 0,
)]))
}
DataType::Extension(_, datatype, _) => generic_placeholder_for_datatype(datatype),
}
}
pub type ComponentReflectionMap = nohash_hasher::IntMap<ComponentName, ComponentReflection>;
#[derive(Clone, Debug)]
pub struct ComponentReflection {
pub docstring_md: &'static str,
pub custom_placeholder: Option<Box<dyn arrow2::array::Array>>,
pub datatype: arrow2::datatypes::DataType,
}
pub type ArchetypeReflectionMap = nohash_hasher::IntMap<ArchetypeName, ArchetypeReflection>;
#[derive(Clone, Debug)]
pub struct ArchetypeReflection {
pub display_name: &'static str,
pub view_types: &'static [&'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)
}
}
#[derive(Clone, Debug)]
pub struct ArchetypeFieldReflection {
pub component_name: ComponentName,
pub display_name: &'static str,
pub docstring_md: &'static str,
pub is_required: bool,
}