use std::{borrow::Cow, sync::Arc};
use crate::{
ComponentBatch, ComponentDescriptor, ComponentName, DeserializationResult, SerializationResult,
SerializedComponentBatch, _Backtrace,
};
#[expect(unused_imports, clippy::unused_trait_names)] use crate::{Component, Loggable, LoggableBatch};
pub trait Archetype {
type Indicator: 'static + ComponentBatch + Default;
fn name() -> ArchetypeName;
fn display_name() -> &'static str;
fn indicator() -> SerializedComponentBatch;
fn required_components() -> std::borrow::Cow<'static, [ComponentDescriptor]>;
#[inline]
fn recommended_components() -> std::borrow::Cow<'static, [ComponentDescriptor]> {
std::borrow::Cow::Owned(vec![Self::indicator().descriptor.clone()])
}
#[inline]
fn optional_components() -> std::borrow::Cow<'static, [ComponentDescriptor]> {
std::borrow::Cow::Borrowed(&[])
}
#[inline]
fn all_components() -> std::borrow::Cow<'static, [ComponentDescriptor]> {
[
Self::required_components().into_owned(),
Self::recommended_components().into_owned(),
Self::optional_components().into_owned(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.into()
}
#[inline]
fn from_arrow(
data: impl IntoIterator<Item = (arrow::datatypes::Field, ::arrow::array::ArrayRef)>,
) -> DeserializationResult<Self>
where
Self: Sized,
{
Self::from_arrow_components(
data.into_iter()
.map(|(field, array)| (ComponentDescriptor::from(field), array)),
)
}
#[inline]
fn from_arrow_components(
data: impl IntoIterator<Item = (ComponentDescriptor, ::arrow::array::ArrayRef)>,
) -> DeserializationResult<Self>
where
Self: Sized,
{
_ = data; Err(crate::DeserializationError::NotImplemented {
fqname: Self::name().to_string(),
backtrace: _Backtrace::new_unresolved(),
})
}
}
pub trait ArchetypeReflectionMarker {}
re_string_interner::declare_new_type!(
#[cfg_attr(feature = "serde", derive(::serde::Deserialize, ::serde::Serialize))]
pub struct ArchetypeName;
);
impl ArchetypeName {
#[inline]
#[track_caller]
pub fn sanity_check(&self) {
let full_name = self.0.as_str();
debug_assert!(
!full_name.starts_with("rerun.archetypes.rerun.archetypes.")
&& !full_name.contains(':'),
"DEBUG ASSERT: Found archetype with full name {full_name:?}. Maybe some bad round-tripping?"
);
}
#[inline]
pub fn full_name(&self) -> &'static str {
self.sanity_check();
self.0.as_str()
}
#[inline]
pub fn short_name(&self) -> &'static str {
self.sanity_check();
let full_name = self.0.as_str();
if let Some(short_name) = full_name.strip_prefix("rerun.archetypes.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.blueprint.archetypes.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.") {
short_name
} else {
full_name
}
}
}
impl re_byte_size::SizeBytes for ArchetypeName {
#[inline]
fn heap_size_bytes(&self) -> u64 {
0
}
}
re_string_interner::declare_new_type!(
#[cfg_attr(feature = "serde", derive(::serde::Deserialize, ::serde::Serialize))]
pub struct ArchetypeFieldName;
);
impl re_byte_size::SizeBytes for ArchetypeFieldName {
#[inline]
fn heap_size_bytes(&self) -> u64 {
0
}
}
#[derive(Debug, Clone, Copy)]
pub struct GenericIndicatorComponent<A: Archetype> {
_phantom: std::marker::PhantomData<A>,
}
impl<A: Archetype> GenericIndicatorComponent<A> {
pub const DEFAULT: Self = Self {
_phantom: std::marker::PhantomData::<A>,
};
#[inline]
pub fn new_array(len: usize) -> GenericIndicatorComponentArray<A> {
GenericIndicatorComponentArray {
len,
_phantom: std::marker::PhantomData::<A>,
}
}
}
impl<A: Archetype> Default for GenericIndicatorComponent<A> {
fn default() -> Self {
Self::DEFAULT
}
}
impl<A: Archetype> crate::LoggableBatch for GenericIndicatorComponent<A> {
#[inline]
fn to_arrow(&self) -> SerializationResult<arrow::array::ArrayRef> {
Ok(Arc::new(arrow::array::NullArray::new(1)))
}
}
impl<A: Archetype> crate::ComponentBatch for GenericIndicatorComponent<A> {
#[inline]
fn descriptor(&self) -> Cow<'_, ComponentDescriptor> {
let component_name =
format!("{}Indicator", A::name().full_name()).replace("archetypes", "components");
ComponentDescriptor::new(component_name).into()
}
}
#[derive(Debug, Clone, Copy)]
pub struct GenericIndicatorComponentArray<A: Archetype> {
len: usize,
_phantom: std::marker::PhantomData<A>,
}
impl<A: Archetype> crate::LoggableBatch for GenericIndicatorComponentArray<A> {
#[inline]
fn to_arrow(&self) -> SerializationResult<arrow::array::ArrayRef> {
Ok(Arc::new(arrow::array::NullArray::new(self.len)))
}
}
impl<A: Archetype> crate::ComponentBatch for GenericIndicatorComponentArray<A> {
#[inline]
fn descriptor(&self) -> Cow<'_, ComponentDescriptor> {
ComponentDescriptor::new(GenericIndicatorComponent::<A>::DEFAULT.name()).into()
}
}
#[derive(Debug, Clone, Copy)]
pub struct NamedIndicatorComponent(pub ComponentName);
impl crate::LoggableBatch for NamedIndicatorComponent {
#[inline]
fn to_arrow(&self) -> SerializationResult<arrow::array::ArrayRef> {
Ok(Arc::new(arrow::array::NullArray::new(1)))
}
}
impl crate::ComponentBatch for NamedIndicatorComponent {
#[inline]
fn descriptor(&self) -> Cow<'_, ComponentDescriptor> {
ComponentDescriptor::new(self.0).into()
}
}