use nohash_hasher::IntMap;
use crate::{
ArchetypeName, Component, ComponentDescriptor, ComponentIdentifier, SerializedComponentBatch,
};
use re_types_core::{try_serialize_field, AsComponents, ComponentType, Loggable};
#[derive(Default)]
pub struct AnyValues {
archetype_name: Option<ArchetypeName>,
batches: IntMap<ComponentIdentifier, SerializedComponentBatch>,
}
impl AnyValues {
#[inline]
pub fn new(archetype_name: impl Into<ArchetypeName>) -> Self {
Self {
archetype_name: Some(archetype_name.into()),
batches: Default::default(),
}
}
#[inline]
pub fn with_field(mut self, field: impl AsRef<str>, array: arrow::array::ArrayRef) -> Self {
let field = field.as_ref();
let component = field.into();
self.batches.insert(
component,
SerializedComponentBatch {
array,
descriptor: ComponentDescriptor {
archetype: self.archetype_name,
component_type: None,
component,
},
},
);
self
}
#[inline]
pub fn with_component<C: Component>(
self,
field: impl AsRef<str>,
loggable: impl IntoIterator<Item = impl Into<C>>,
) -> Self {
self.with_loggable(field, C::name(), loggable)
}
#[inline]
pub fn with_loggable<L: Loggable>(
mut self,
field: impl AsRef<str>,
component_type: impl Into<ComponentType>,
loggable: impl IntoIterator<Item = impl Into<L>>,
) -> Self {
let field = field.as_ref();
let component = field.into();
try_serialize_field(
ComponentDescriptor {
archetype: self.archetype_name,
component,
component_type: Some(component_type.into()),
},
loggable,
)
.and_then(|serialized| self.batches.insert(component, serialized));
self
}
}
impl AsComponents for AnyValues {
fn as_serialized_batches(&self) -> Vec<SerializedComponentBatch> {
self.batches.values().cloned().collect()
}
}
#[cfg(test)]
mod test {
use std::collections::BTreeSet;
use crate::components;
use super::*;
#[test]
fn without_archetype() {
let values = AnyValues::default()
.with_component::<components::Scalar>("confidence", [1.2f64, 3.4, 5.6])
.with_loggable::<components::Text>("homepage", "user.url", vec!["https://www.rerun.io"])
.with_field(
"description",
std::sync::Arc::new(arrow::array::StringArray::from(vec!["Bla bla bla…"])),
);
let actual = values
.as_serialized_batches()
.into_iter()
.map(|batch| batch.descriptor)
.collect::<BTreeSet<_>>();
assert_eq!(
actual,
[
ComponentDescriptor::partial("confidence")
.with_component_type(components::Scalar::name()),
ComponentDescriptor::partial("homepage").with_component_type("user.url".into()),
ComponentDescriptor::partial("description"),
]
.into_iter()
.collect()
);
}
#[test]
fn with_archetype() {
let values = AnyValues::new("MyExample")
.with_component::<components::Scalar>("confidence", [1.2f64, 3.4, 5.6])
.with_loggable::<components::Text>("homepage", "user.url", vec!["https://www.rerun.io"])
.with_field(
"description",
std::sync::Arc::new(arrow::array::StringArray::from(vec!["Bla bla bla…"])),
);
let actual = values
.as_serialized_batches()
.into_iter()
.map(|batch| batch.descriptor)
.collect::<BTreeSet<_>>();
assert_eq!(
actual,
[
ComponentDescriptor::partial("confidence")
.with_archetype("MyExample".into())
.with_component_type(components::Scalar::name()),
ComponentDescriptor::partial("homepage")
.with_component_type("user.url".into())
.with_archetype("MyExample".into()),
ComponentDescriptor::partial("description").with_archetype("MyExample".into()),
]
.into_iter()
.collect()
);
}
}