use nohash_hasher::IntSet;
use re_byte_size::SizeBytes;
use crate::{ComponentIdentifier, DeserializationResult, SerializationResult};
#[expect(unused_imports, clippy::unused_trait_names)] use crate::{Archetype, ComponentBatch};
pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes {
fn arrow_datatype() -> arrow::datatypes::DataType;
#[inline]
fn arrow_empty() -> arrow::array::ArrayRef {
arrow::array::new_empty_array(&Self::arrow_datatype())
}
#[inline]
fn to_arrow<'a>(
data: impl IntoIterator<Item = impl Into<std::borrow::Cow<'a, Self>>>,
) -> SerializationResult<arrow::array::ArrayRef>
where
Self: 'a,
{
Self::to_arrow_opt(data.into_iter().map(|v| Some(v)))
}
fn to_arrow_opt<'a>(
data: impl IntoIterator<Item = Option<impl Into<std::borrow::Cow<'a, Self>>>>,
) -> SerializationResult<arrow::array::ArrayRef>
where
Self: 'a;
#[inline]
fn from_arrow(data: &dyn arrow::array::Array) -> DeserializationResult<Vec<Self>> {
Self::from_arrow_opt(data)?
.into_iter()
.map(|opt| opt.ok_or_else(crate::DeserializationError::missing_data))
.collect::<DeserializationResult<Vec<_>>>()
}
#[inline]
fn from_arrow_opt(
data: &dyn arrow::array::Array,
) -> crate::DeserializationResult<Vec<Option<Self>>> {
Self::from_arrow(data).map(|v| v.into_iter().map(Some).collect())
}
fn verify_arrow_array(data: &dyn arrow::array::Array) -> crate::DeserializationResult<()> {
Self::from_arrow(data).map(|_| ())
}
}
pub trait Component: Loggable {
fn name() -> ComponentType;
}
pub type UnorderedComponentSet = IntSet<ComponentIdentifier>;
pub type ComponentSet = std::collections::BTreeSet<ComponentIdentifier>;
re_string_interner::declare_new_type!(
#[cfg_attr(feature = "serde", derive(::serde::Deserialize, ::serde::Serialize))]
pub struct ComponentType;
);
impl ComponentType {
#[inline]
#[track_caller]
pub fn sanity_check(&self) {
let full_type = self.0.as_str();
debug_assert!(
!full_type.starts_with("rerun.components.rerun.components."),
"DEBUG ASSERT: Found component with full type {full_type:?}. 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.blueprint.components.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.components.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.controls.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.") {
short_name
} else {
full_name
}
}
pub fn doc_url(&self) -> Option<String> {
if let Some(component_type_pascal_case) = self.full_name().strip_prefix("rerun.components.")
{
let component_type_snake_case = re_case::to_snake_case(component_type_pascal_case);
let base_url = "https://rerun.io/docs/reference/types/components";
Some(format!("{base_url}/{component_type_snake_case}"))
} else {
None }
}
pub fn matches(&self, other: &str) -> bool {
self.0.as_str() == other
|| self.full_name().to_lowercase() == other.to_lowercase()
|| self.short_name().to_lowercase() == other.to_lowercase()
}
}
impl re_byte_size::SizeBytes for ComponentType {
#[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 DatatypeName;
);
impl DatatypeName {
#[inline]
pub fn full_name(&self) -> &'static str {
self.0.as_str()
}
#[inline]
pub fn short_name(&self) -> &'static str {
let full_name = self.0.as_str();
if let Some(short_name) = full_name.strip_prefix("rerun.datatypes.") {
short_name
} else if let Some(short_name) = full_name.strip_prefix("rerun.") {
short_name
} else {
full_name
}
}
}
impl re_byte_size::SizeBytes for DatatypeName {
#[inline]
fn heap_size_bytes(&self) -> u64 {
0
}
}