use re_chunk::external::nohash_hasher::{IntMap, IsEnabled};
use re_chunk::{
Chunk, EntityPath, TimeColumn, TimeColumnBuilder, TimePoint, Timeline, TimelineName,
};
use re_log_types::{TimeCell, TimeType};
use crate::util::{TimestampCell, log_and_publish_timepoint_from_msg};
pub trait MessageParser {
fn append(&mut self, ctx: &mut ParserContext, msg: &mcap::Message<'_>) -> anyhow::Result<()>;
fn get_log_and_publish_timepoints(
&self,
msg: &mcap::Message<'_>,
time_type: TimeType,
) -> anyhow::Result<Vec<re_chunk::TimePoint>> {
Ok(vec![log_and_publish_timepoint_from_msg(msg, time_type)])
}
fn finalize(self: Box<Self>, ctx: ParserContext) -> anyhow::Result<Vec<Chunk>>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ChannelId(pub u16);
impl From<u16> for ChannelId {
fn from(id: u16) -> Self {
Self(id)
}
}
impl IsEnabled for ChannelId {}
pub struct ParserContext {
entity_path: EntityPath,
channel_topic: String,
time_type: TimeType,
pub timelines: IntMap<TimelineName, TimeColumnBuilder>,
}
impl ParserContext {
pub fn new(
entity_path: EntityPath,
channel_topic: impl Into<String>,
time_type: TimeType,
) -> Self {
Self {
entity_path,
channel_topic: channel_topic.into(),
time_type,
timelines: IntMap::default(),
}
}
pub fn time_type(&self) -> TimeType {
self.time_type
}
pub fn add_timepoint(&mut self, timepoint: TimePoint) -> &mut Self {
for (timeline, cell) in timepoint {
self.timelines
.entry(timeline)
.or_insert_with(|| TimeColumn::builder(Timeline::new(timeline, cell.typ)))
.with_row(cell.value);
}
self
}
pub fn add_time_cell(
&mut self,
timeline_name: impl Into<TimelineName>,
cell: TimeCell,
) -> &mut Self {
let timeline_name = timeline_name.into();
self.timelines
.entry(timeline_name)
.or_insert_with(|| TimeColumn::builder(Timeline::new(timeline_name, cell.typ)))
.with_row(cell.value);
self
}
pub fn add_timestamp_cell(&mut self, timestamp_cell: TimestampCell) -> &mut Self {
let timeline_name = TimelineName::from(timestamp_cell.timeline_name());
let cell = timestamp_cell.into_time_cell();
self.timelines
.entry(timeline_name)
.or_insert_with(|| TimeColumn::builder(Timeline::new(timeline_name, cell.typ)))
.with_row(cell.value);
self
}
pub fn build_timelines(self) -> IntMap<TimelineName, TimeColumn> {
self.timelines
.into_iter()
.map(|(name, builder)| (name, builder.build()))
.collect()
}
pub fn entity_path(&self) -> &EntityPath {
&self.entity_path
}
pub fn channel_topic(&self) -> &str {
&self.channel_topic
}
}