re_log_encoding/
app_id_injector.rs

1use std::collections::HashMap;
2
3use re_log_types::{ApplicationId, RecordingId, StoreId, StoreInfo, StoreKind};
4use re_protos::common::v1alpha1::ext::StoreIdMissingApplicationIdError;
5
6/// Helper trait for injecting application ids to legacy `StoreId` protobuf messages which miss it.
7///
8/// Before 0.25, the `StoreId` protobuf didn't contain an application id, which was only provided by
9/// `StoreInfo`. As a result, messages such as `ArrowMsg` didn't contain an application id. Only
10/// `SetStoreInfo` did. This helper trait expose an interface to cache the application id from
11/// `SetStoreInfo` and inject it into later messages.
12///
13/// Note: this is a trait to allow disabling this mechanism and injecting dummy application ids
14/// instead, see [`DummyApplicationIdInjector`], which is needed on redap side.
15//TODO(#10730): this should be entirely suppressed when removing 0.24 back compat
16pub trait ApplicationIdInjector {
17    /// Populate the cache based on a [`re_log_types::SetStoreInfo`] payload.
18    fn store_info_received(&mut self, store_info: &StoreInfo);
19
20    /// Try to recover a `StoreId` from a `StoreIdMissingApplicationIdError`.
21    fn recover_store_id(&self, store_id_err: StoreIdMissingApplicationIdError) -> Option<StoreId>;
22}
23
24/// Implements [`ApplicationIdInjector`] by caching the application ids from `StoreInfo`.
25#[derive(Default)]
26pub struct CachingApplicationIdInjector(HashMap<(RecordingId, StoreKind), ApplicationId>);
27
28impl ApplicationIdInjector for CachingApplicationIdInjector {
29    fn store_info_received(&mut self, store_info: &StoreInfo) {
30        self.0.insert(
31            (
32                store_info.recording_id().clone(),
33                store_info.store_id.kind(),
34            ),
35            store_info.application_id().clone(),
36        );
37    }
38
39    fn recover_store_id(&self, store_id_err: StoreIdMissingApplicationIdError) -> Option<StoreId> {
40        let StoreIdMissingApplicationIdError {
41            store_kind,
42            recording_id,
43        } = store_id_err;
44
45        self.0
46            .get(&(recording_id.clone(), store_kind))
47            .cloned()
48            .map(|app_id| StoreId::new(store_kind, app_id, recording_id))
49    }
50}
51
52/// Implements [`ApplicationIdInjector`] by returning a constant, dummy application id.
53///
54/// Do not use this unless you are sure that the application id is not needed.
55pub struct DummyApplicationIdInjector {
56    application_id: ApplicationId,
57}
58
59impl DummyApplicationIdInjector {
60    pub fn new(application_id: impl Into<ApplicationId>) -> Self {
61        Self {
62            application_id: application_id.into(),
63        }
64    }
65}
66
67impl ApplicationIdInjector for DummyApplicationIdInjector {
68    fn store_info_received(&mut self, _store_info: &StoreInfo) {
69        // No-op, as this is a dummy injector.
70    }
71
72    fn recover_store_id(&self, store_id_err: StoreIdMissingApplicationIdError) -> Option<StoreId> {
73        Some(StoreId::new(
74            store_id_err.store_kind,
75            self.application_id.clone(),
76            store_id_err.recording_id,
77        ))
78    }
79}