re_protos/v1alpha1/
rerun.common.v1alpha1.ext.rs

1use arrow::{datatypes::Schema as ArrowSchema, error::ArrowError};
2
3use re_log_types::{RecordingId, StoreKind, TableId, external::re_types_core::ComponentDescriptor};
4
5use crate::{TypeConversionError, invalid_field, missing_field};
6
7// --- Arrow ---
8
9impl TryFrom<&crate::common::v1alpha1::Schema> for ArrowSchema {
10    type Error = ArrowError;
11
12    fn try_from(value: &crate::common::v1alpha1::Schema) -> Result<Self, Self::Error> {
13        let schema_bytes = value
14            .arrow_schema
15            .as_ref()
16            .ok_or(ArrowError::InvalidArgumentError(
17                "missing schema bytes".to_owned(),
18            ))?;
19        Ok(Self::clone(
20            re_sorbet::migrated_schema_from_ipc(schema_bytes)?.as_ref(),
21        ))
22    }
23}
24
25impl TryFrom<&ArrowSchema> for crate::common::v1alpha1::Schema {
26    type Error = ArrowError;
27
28    fn try_from(value: &ArrowSchema) -> Result<Self, Self::Error> {
29        Ok(Self {
30            arrow_schema: Some(re_sorbet::ipc_from_schema(value)?.into()),
31        })
32    }
33}
34
35impl TryFrom<crate::common::v1alpha1::Schema> for ArrowSchema {
36    type Error = ArrowError;
37
38    fn try_from(value: crate::common::v1alpha1::Schema) -> Result<Self, Self::Error> {
39        (&value).try_into()
40    }
41}
42
43// --- EntryId ---
44
45impl From<re_log_types::EntryId> for crate::common::v1alpha1::EntryId {
46    #[inline]
47    fn from(value: re_log_types::EntryId) -> Self {
48        Self {
49            id: Some(value.id.into()),
50        }
51    }
52}
53
54impl TryFrom<crate::common::v1alpha1::EntryId> for re_log_types::EntryId {
55    type Error = TypeConversionError;
56
57    fn try_from(value: crate::common::v1alpha1::EntryId) -> Result<Self, Self::Error> {
58        let id = value
59            .id
60            .ok_or(missing_field!(crate::common::v1alpha1::EntryId, "id"))?;
61        Ok(Self { id: id.try_into()? })
62    }
63}
64
65// shortcuts
66
67impl From<re_tuid::Tuid> for crate::common::v1alpha1::EntryId {
68    fn from(id: re_tuid::Tuid) -> Self {
69        let id: re_log_types::EntryId = id.into();
70        Self {
71            id: Some(id.id.into()),
72        }
73    }
74}
75
76impl TryFrom<crate::common::v1alpha1::Tuid> for crate::common::v1alpha1::EntryId {
77    type Error = TypeConversionError;
78
79    fn try_from(id: crate::common::v1alpha1::Tuid) -> Result<Self, Self::Error> {
80        let id: re_tuid::Tuid = id.try_into()?;
81        Ok(Self {
82            id: Some(id.into()),
83        })
84    }
85}
86
87// --- PartitionId ---
88
89#[derive(
90    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
91)]
92pub struct PartitionId {
93    pub id: String,
94}
95
96impl PartitionId {
97    #[inline]
98    pub fn new(id: String) -> Self {
99        Self { id }
100    }
101}
102
103impl From<String> for PartitionId {
104    fn from(id: String) -> Self {
105        Self { id }
106    }
107}
108
109impl From<&str> for PartitionId {
110    fn from(id: &str) -> Self {
111        Self { id: id.to_owned() }
112    }
113}
114
115impl std::fmt::Display for PartitionId {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        self.id.fmt(f)
118    }
119}
120
121impl TryFrom<crate::common::v1alpha1::PartitionId> for PartitionId {
122    type Error = TypeConversionError;
123
124    fn try_from(value: crate::common::v1alpha1::PartitionId) -> Result<Self, Self::Error> {
125        Ok(Self {
126            id: value
127                .id
128                .ok_or(missing_field!(crate::common::v1alpha1::PartitionId, "id"))?,
129        })
130    }
131}
132
133impl From<PartitionId> for crate::common::v1alpha1::PartitionId {
134    fn from(value: PartitionId) -> Self {
135        Self { id: Some(value.id) }
136    }
137}
138
139impl AsRef<str> for PartitionId {
140    fn as_ref(&self) -> &str {
141        self.id.as_str()
142    }
143}
144
145// shortcuts
146
147impl From<String> for crate::common::v1alpha1::PartitionId {
148    fn from(id: String) -> Self {
149        Self { id: Some(id) }
150    }
151}
152
153impl From<&str> for crate::common::v1alpha1::PartitionId {
154    fn from(id: &str) -> Self {
155        Self {
156            id: Some(id.to_owned()),
157        }
158    }
159}
160
161// --- DatasetHandle ---
162
163#[derive(Debug, Clone)]
164pub struct DatasetHandle {
165    pub id: Option<re_log_types::EntryId>,
166    pub store_kind: StoreKind,
167    pub url: url::Url,
168}
169
170impl DatasetHandle {
171    /// Create a new dataset handle
172    pub fn new(url: url::Url, store_kind: StoreKind) -> Self {
173        Self {
174            id: None,
175            store_kind,
176            url,
177        }
178    }
179}
180
181impl TryFrom<crate::common::v1alpha1::DatasetHandle> for DatasetHandle {
182    type Error = TypeConversionError;
183
184    fn try_from(value: crate::common::v1alpha1::DatasetHandle) -> Result<Self, Self::Error> {
185        Ok(Self {
186            id: value.entry_id.map(|id| id.try_into()).transpose()?,
187            store_kind: crate::common::v1alpha1::StoreKind::try_from(value.store_kind)?.into(),
188            url: value
189                .dataset_url
190                .ok_or(missing_field!(
191                    crate::common::v1alpha1::DatasetHandle,
192                    "dataset_url"
193                ))?
194                .parse()
195                .map_err(|err| {
196                    invalid_field!(crate::common::v1alpha1::DatasetHandle, "dataset_url", err)
197                })?,
198        })
199    }
200}
201
202impl From<DatasetHandle> for crate::common::v1alpha1::DatasetHandle {
203    fn from(value: DatasetHandle) -> Self {
204        Self {
205            entry_id: value.id.map(Into::into),
206            store_kind: crate::common::v1alpha1::StoreKind::from(value.store_kind) as i32,
207            dataset_url: Some(value.url.to_string()),
208        }
209    }
210}
211
212// ---
213
214impl TryFrom<crate::common::v1alpha1::Tuid> for re_tuid::Tuid {
215    type Error = TypeConversionError;
216
217    fn try_from(value: crate::common::v1alpha1::Tuid) -> Result<Self, Self::Error> {
218        let time_ns = value
219            .time_ns
220            .ok_or(missing_field!(crate::common::v1alpha1::Tuid, "time_ns"))?;
221        let inc = value
222            .inc
223            .ok_or(missing_field!(crate::common::v1alpha1::Tuid, "inc"))?;
224
225        Ok(Self::from_nanos_and_inc(time_ns, inc))
226    }
227}
228
229impl From<re_tuid::Tuid> for crate::common::v1alpha1::Tuid {
230    fn from(value: re_tuid::Tuid) -> Self {
231        Self {
232            time_ns: Some(value.nanos_since_epoch()),
233            inc: Some(value.inc()),
234        }
235    }
236}
237
238impl From<re_log_types::EntityPath> for crate::common::v1alpha1::EntityPath {
239    fn from(value: re_log_types::EntityPath) -> Self {
240        Self {
241            path: value.to_string(),
242        }
243    }
244}
245
246impl TryFrom<crate::common::v1alpha1::EntityPath> for re_log_types::EntityPath {
247    type Error = TypeConversionError;
248
249    fn try_from(value: crate::common::v1alpha1::EntityPath) -> Result<Self, Self::Error> {
250        Self::parse_strict(&value.path)
251            .map_err(|err| invalid_field!(crate::common::v1alpha1::EntityPath, "path", err))
252    }
253}
254
255impl From<re_log_types::AbsoluteTimeRange> for crate::common::v1alpha1::TimeRange {
256    fn from(value: re_log_types::AbsoluteTimeRange) -> Self {
257        Self {
258            start: value.min().as_i64(),
259            end: value.max().as_i64(),
260        }
261    }
262}
263
264impl From<crate::common::v1alpha1::TimeRange> for re_log_types::AbsoluteTimeRange {
265    fn from(value: crate::common::v1alpha1::TimeRange) -> Self {
266        Self::new(
267            re_log_types::TimeInt::new_temporal(value.start),
268            re_log_types::TimeInt::new_temporal(value.end),
269        )
270    }
271}
272
273impl From<re_log_types::AbsoluteTimeRange> for crate::common::v1alpha1::IndexRange {
274    fn from(value: re_log_types::AbsoluteTimeRange) -> Self {
275        Self {
276            time_range: Some(value.into()),
277        }
278    }
279}
280
281impl TryFrom<crate::common::v1alpha1::IndexRange> for re_log_types::AbsoluteTimeRange {
282    type Error = TypeConversionError;
283
284    fn try_from(value: crate::common::v1alpha1::IndexRange) -> Result<Self, Self::Error> {
285        value
286            .time_range
287            .ok_or(missing_field!(
288                crate::common::v1alpha1::IndexRange,
289                "time_range"
290            ))
291            .map(|time_range| Self::new(time_range.start, time_range.end))
292    }
293}
294
295impl From<crate::common::v1alpha1::Timeline> for re_log_types::TimelineName {
296    fn from(value: crate::common::v1alpha1::Timeline) -> Self {
297        Self::new(&value.name)
298    }
299}
300
301impl From<re_log_types::TimelineName> for crate::common::v1alpha1::Timeline {
302    fn from(value: re_log_types::TimelineName) -> Self {
303        Self {
304            name: value.to_string(),
305        }
306    }
307}
308
309impl From<re_log_types::Timeline> for crate::common::v1alpha1::Timeline {
310    fn from(value: re_log_types::Timeline) -> Self {
311        Self {
312            name: value.name().to_string(),
313        }
314    }
315}
316
317impl TryFrom<crate::common::v1alpha1::IndexColumnSelector> for re_log_types::TimelineName {
318    type Error = TypeConversionError;
319
320    fn try_from(value: crate::common::v1alpha1::IndexColumnSelector) -> Result<Self, Self::Error> {
321        let timeline = value.timeline.ok_or(missing_field!(
322            crate::common::v1alpha1::IndexColumnSelector,
323            "timeline"
324        ))?;
325        Ok(timeline.into())
326    }
327}
328
329impl From<re_log_types::TimelineName> for crate::common::v1alpha1::IndexColumnSelector {
330    fn from(value: re_log_types::TimelineName) -> Self {
331        Self {
332            timeline: Some(value.into()),
333        }
334    }
335}
336
337impl From<crate::common::v1alpha1::ApplicationId> for re_log_types::ApplicationId {
338    #[inline]
339    fn from(value: crate::common::v1alpha1::ApplicationId) -> Self {
340        Self::from(value.id)
341    }
342}
343
344impl From<re_log_types::ApplicationId> for crate::common::v1alpha1::ApplicationId {
345    #[inline]
346    fn from(value: re_log_types::ApplicationId) -> Self {
347        Self {
348            id: value.to_string(),
349        }
350    }
351}
352
353impl From<crate::common::v1alpha1::StoreKind> for re_log_types::StoreKind {
354    #[inline]
355    fn from(value: crate::common::v1alpha1::StoreKind) -> Self {
356        match value {
357            crate::common::v1alpha1::StoreKind::Unspecified
358            | crate::common::v1alpha1::StoreKind::Recording => Self::Recording,
359            crate::common::v1alpha1::StoreKind::Blueprint => Self::Blueprint,
360        }
361    }
362}
363
364impl From<re_log_types::StoreKind> for crate::common::v1alpha1::StoreKind {
365    #[inline]
366    fn from(value: re_log_types::StoreKind) -> Self {
367        match value {
368            re_log_types::StoreKind::Recording => Self::Recording,
369            re_log_types::StoreKind::Blueprint => Self::Blueprint,
370        }
371    }
372}
373
374/// The store id failed to deserialize due to missing application id.
375///
376/// This may happen when migrating older RRD (before application ID was moved to `StoreId`). This
377/// error can be recovered from if the application ID is known.
378//TODO(#10730): this is specifically for 0.24 back compat. Switch to `TypeConversionError` when cleaning up.
379#[derive(Debug, Clone)]
380pub struct StoreIdMissingApplicationIdError {
381    pub store_kind: re_log_types::StoreKind,
382    pub recording_id: RecordingId,
383}
384
385impl StoreIdMissingApplicationIdError {
386    /// Recover the store ID by providing the application ID.
387    pub fn recover(self, application_id: re_log_types::ApplicationId) -> re_log_types::StoreId {
388        re_log_types::StoreId::new(self.store_kind, application_id, self.recording_id)
389    }
390
391    #[inline]
392    pub fn into_type_conversion_error(self, msg: impl Into<String>) -> TypeConversionError {
393        TypeConversionError::LegacyStoreIdError(format!(
394            "{} (kind: {}, recording_id: {})",
395            msg.into(),
396            self.store_kind,
397            self.recording_id
398        ))
399    }
400}
401
402/// Convert a store id
403impl TryFrom<crate::common::v1alpha1::StoreId> for re_log_types::StoreId {
404    type Error = StoreIdMissingApplicationIdError;
405
406    #[inline]
407    fn try_from(value: crate::common::v1alpha1::StoreId) -> Result<Self, Self::Error> {
408        let store_kind = value.kind().into();
409        let recording_id = RecordingId::from(value.recording_id);
410
411        //TODO(#10730): switch to `TypeConversionError` when cleaning up 0.24 back compat
412        match value.application_id {
413            None => Err(StoreIdMissingApplicationIdError {
414                store_kind,
415                recording_id,
416            }),
417            Some(application_id) => Ok(re_log_types::StoreId::new(
418                store_kind,
419                application_id,
420                recording_id,
421            )),
422        }
423    }
424}
425
426impl From<re_log_types::StoreId> for crate::common::v1alpha1::StoreId {
427    #[inline]
428    fn from(value: re_log_types::StoreId) -> Self {
429        let kind: crate::common::v1alpha1::StoreKind = value.kind().into();
430        Self {
431            kind: kind as i32,
432            recording_id: value.recording_id().as_str().to_owned(),
433            application_id: Some(value.application_id().clone().into()),
434        }
435    }
436}
437
438impl From<re_log_types::TableId> for crate::common::v1alpha1::TableId {
439    #[inline]
440    fn from(value: re_log_types::TableId) -> Self {
441        Self {
442            id: value.as_str().to_owned(),
443        }
444    }
445}
446
447impl From<crate::common::v1alpha1::TableId> for re_log_types::TableId {
448    #[inline]
449    fn from(value: crate::common::v1alpha1::TableId) -> Self {
450        TableId::from(value.id)
451    }
452}
453
454// --- Scanning & Querying ---
455
456#[derive(Debug, Default, Clone)]
457pub struct ScanParameters {
458    pub columns: Vec<String>,
459    pub on_missing_columns: IfMissingBehavior,
460    pub filter: Option<String>,
461    pub limit_offset: Option<i64>,
462    pub limit_len: Option<i64>,
463    pub order_by: Vec<ScanParametersOrderClause>,
464    pub explain_plan: bool,
465    pub explain_filter: bool,
466}
467
468impl TryFrom<crate::common::v1alpha1::ScanParameters> for ScanParameters {
469    type Error = TypeConversionError;
470
471    fn try_from(value: crate::common::v1alpha1::ScanParameters) -> Result<Self, Self::Error> {
472        Ok(Self {
473            columns: value.columns,
474            on_missing_columns: crate::common::v1alpha1::IfMissingBehavior::try_from(
475                value.on_missing_columns,
476            )?
477            .into(),
478            filter: value.filter,
479            limit_offset: value.limit_offset,
480            limit_len: value.limit_len,
481            order_by: value
482                .order_by
483                .into_iter()
484                .map(|ob| ob.try_into())
485                .collect::<Result<Vec<_>, _>>()?,
486            explain_plan: value.explain_plan,
487            explain_filter: value.explain_filter,
488        })
489    }
490}
491
492impl From<ScanParameters> for crate::common::v1alpha1::ScanParameters {
493    fn from(value: ScanParameters) -> Self {
494        Self {
495            columns: value.columns,
496            on_missing_columns: crate::common::v1alpha1::IfMissingBehavior::from(
497                value.on_missing_columns,
498            ) as _,
499            filter: value.filter,
500            limit_offset: value.limit_offset,
501            limit_len: value.limit_len,
502            order_by: value.order_by.into_iter().map(|ob| ob.into()).collect(),
503            explain_plan: value.explain_plan,
504            explain_filter: value.explain_filter,
505        }
506    }
507}
508
509#[derive(Debug, Default, Clone)]
510pub struct ScanParametersOrderClause {
511    pub descending: bool,
512    pub nulls_last: bool,
513    pub column_name: String,
514}
515
516impl TryFrom<crate::common::v1alpha1::ScanParametersOrderClause> for ScanParametersOrderClause {
517    type Error = TypeConversionError;
518
519    fn try_from(
520        value: crate::common::v1alpha1::ScanParametersOrderClause,
521    ) -> Result<Self, Self::Error> {
522        Ok(Self {
523            descending: value.descending,
524            nulls_last: value.nulls_last,
525            column_name: value.column_name.ok_or(missing_field!(
526                crate::common::v1alpha1::ScanParametersOrderClause,
527                "column_name"
528            ))?,
529        })
530    }
531}
532
533impl From<ScanParametersOrderClause> for crate::common::v1alpha1::ScanParametersOrderClause {
534    fn from(value: ScanParametersOrderClause) -> Self {
535        Self {
536            descending: value.descending,
537            nulls_last: value.nulls_last,
538            column_name: Some(value.column_name),
539        }
540    }
541}
542
543#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
544pub enum IfMissingBehavior {
545    Skip,
546    Error,
547}
548
549impl Default for IfMissingBehavior {
550    fn default() -> Self {
551        Self::Skip
552    }
553}
554
555impl From<crate::common::v1alpha1::IfMissingBehavior> for IfMissingBehavior {
556    fn from(value: crate::common::v1alpha1::IfMissingBehavior) -> Self {
557        use crate::common::v1alpha1 as common;
558        match value {
559            common::IfMissingBehavior::Unspecified | common::IfMissingBehavior::Skip => Self::Skip,
560            common::IfMissingBehavior::Error => Self::Error,
561        }
562    }
563}
564
565impl From<IfMissingBehavior> for crate::common::v1alpha1::IfMissingBehavior {
566    fn from(value: IfMissingBehavior) -> Self {
567        match value {
568            IfMissingBehavior::Skip => Self::Skip,
569            IfMissingBehavior::Error => Self::Error,
570        }
571    }
572}
573
574#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
575pub enum IfDuplicateBehavior {
576    Overwrite,
577    Skip,
578    Error,
579}
580
581impl Default for IfDuplicateBehavior {
582    fn default() -> Self {
583        Self::Skip
584    }
585}
586
587impl TryFrom<i32> for IfDuplicateBehavior {
588    type Error = TypeConversionError;
589
590    fn try_from(value: i32) -> Result<Self, TypeConversionError> {
591        let proto_value = crate::common::v1alpha1::IfDuplicateBehavior::try_from(value)?;
592        Ok(Self::from(proto_value))
593    }
594}
595
596impl From<crate::common::v1alpha1::IfDuplicateBehavior> for IfDuplicateBehavior {
597    fn from(value: crate::common::v1alpha1::IfDuplicateBehavior) -> Self {
598        use crate::common::v1alpha1 as common;
599        match value {
600            common::IfDuplicateBehavior::Unspecified | common::IfDuplicateBehavior::Skip => {
601                Self::Skip
602            }
603            common::IfDuplicateBehavior::Overwrite => Self::Overwrite,
604            common::IfDuplicateBehavior::Error => Self::Error,
605        }
606    }
607}
608
609impl From<IfDuplicateBehavior> for crate::common::v1alpha1::IfDuplicateBehavior {
610    fn from(value: IfDuplicateBehavior) -> Self {
611        match value {
612            IfDuplicateBehavior::Overwrite => Self::Overwrite,
613            IfDuplicateBehavior::Skip => Self::Skip,
614            IfDuplicateBehavior::Error => Self::Error,
615        }
616    }
617}
618
619// ---
620
621impl From<ComponentDescriptor> for crate::common::v1alpha1::ComponentDescriptor {
622    fn from(value: ComponentDescriptor) -> Self {
623        Self {
624            archetype: value.archetype.map(|n| n.full_name().to_owned()),
625            component: Some(value.component.to_string()),
626            component_type: value.component_type.map(|c| c.full_name().to_owned()),
627        }
628    }
629}
630
631impl TryFrom<crate::common::v1alpha1::ComponentDescriptor> for ComponentDescriptor {
632    type Error = TypeConversionError;
633
634    fn try_from(value: crate::common::v1alpha1::ComponentDescriptor) -> Result<Self, Self::Error> {
635        let crate::common::v1alpha1::ComponentDescriptor {
636            archetype,
637            component,
638            component_type,
639        } = value;
640
641        let component = component.ok_or(missing_field!(
642            crate::common::v1alpha1::ComponentDescriptor,
643            "component"
644        ))?;
645
646        Ok(ComponentDescriptor {
647            archetype: archetype.map(Into::into),
648            component: component.into(),
649            component_type: component_type.map(Into::into),
650        })
651    }
652}
653
654// ---
655
656impl From<re_build_info::BuildInfo> for crate::common::v1alpha1::BuildInfo {
657    fn from(build_info: re_build_info::BuildInfo) -> Self {
658        Self {
659            crate_name: Some(build_info.crate_name.to_string()),
660            features: Some(build_info.features.to_string()),
661            version: Some(build_info.version.into()),
662            rustc_version: Some(build_info.rustc_version.to_string()),
663            llvm_version: Some(build_info.llvm_version.to_string()),
664            git_hash: Some(build_info.git_hash.to_string()),
665            git_branch: Some(build_info.git_branch.to_string()),
666            target_triple: Some(build_info.target_triple.to_string()),
667            build_time: Some(build_info.datetime.to_string()),
668            is_debug_build: Some(build_info.is_debug_build),
669        }
670    }
671}
672
673impl From<crate::common::v1alpha1::BuildInfo> for re_build_info::BuildInfo {
674    fn from(build_info: crate::common::v1alpha1::BuildInfo) -> Self {
675        Self {
676            crate_name: build_info.crate_name().to_owned().into(),
677            features: build_info.features().to_owned().into(),
678            version: build_info.version.clone().unwrap_or_default().into(),
679            rustc_version: build_info.rustc_version().to_owned().into(),
680            llvm_version: build_info.llvm_version().to_owned().into(),
681            git_hash: build_info.git_hash().to_owned().into(),
682            git_branch: build_info.git_branch().to_owned().into(),
683            is_in_rerun_workspace: false,
684            target_triple: build_info.target_triple().to_owned().into(),
685            datetime: build_info.build_time().to_owned().into(),
686            is_debug_build: build_info.is_debug_build(),
687        }
688    }
689}
690
691impl From<re_build_info::CrateVersion> for crate::common::v1alpha1::SemanticVersion {
692    fn from(version: re_build_info::CrateVersion) -> Self {
693        crate::common::v1alpha1::SemanticVersion {
694            major: Some(version.major.into()),
695            minor: Some(version.minor.into()),
696            patch: Some(version.patch.into()),
697            meta: version.meta.map(Into::into),
698        }
699    }
700}
701
702impl From<crate::common::v1alpha1::SemanticVersion> for re_build_info::CrateVersion {
703    fn from(version: crate::common::v1alpha1::SemanticVersion) -> Self {
704        Self {
705            major: version.major() as u8,
706            minor: version.minor() as u8,
707            patch: version.patch() as u8,
708            meta: version.meta.map(Into::into),
709        }
710    }
711}
712
713impl From<re_build_info::Meta> for crate::common::v1alpha1::semantic_version::Meta {
714    fn from(version_meta: re_build_info::Meta) -> Self {
715        match version_meta {
716            re_build_info::Meta::Rc(v) => Self::Rc(v.into()),
717
718            re_build_info::Meta::Alpha(v) => Self::Alpha(v.into()),
719
720            re_build_info::Meta::DevAlpha { alpha, commit } => {
721                Self::DevAlpha(crate::common::v1alpha1::DevAlpha {
722                    alpha: Some(alpha.into()),
723                    commit: commit.map(|s| String::from_utf8_lossy(s).to_string()),
724                })
725            }
726        }
727    }
728}
729
730impl From<crate::common::v1alpha1::semantic_version::Meta> for re_build_info::Meta {
731    fn from(version_meta: crate::common::v1alpha1::semantic_version::Meta) -> Self {
732        match version_meta {
733            crate::common::v1alpha1::semantic_version::Meta::Rc(v) => Self::Rc(v as _),
734
735            crate::common::v1alpha1::semantic_version::Meta::Alpha(v) => Self::Alpha(v as _),
736
737            crate::common::v1alpha1::semantic_version::Meta::DevAlpha(dev_alpha) => {
738                Self::DevAlpha {
739                    alpha: dev_alpha.alpha() as u8,
740                    // TODO(cmc): support this, but that means DevAlpha is not-const
741                    // anymore, which trigger a chain reaction of changes that I really
742                    // don't want to get in right now.
743                    commit: None,
744                }
745            }
746        }
747    }
748}
749
750// ---
751
752#[cfg(test)]
753mod tests {
754
755    #[test]
756    fn entity_path_conversion() {
757        let entity_path = re_log_types::EntityPath::parse_strict("a/b/c").unwrap();
758        let proto_entity_path: crate::common::v1alpha1::EntityPath = entity_path.clone().into();
759        let entity_path2: re_log_types::EntityPath = proto_entity_path.try_into().unwrap();
760        assert_eq!(entity_path, entity_path2);
761    }
762
763    #[test]
764    fn time_range_conversion() {
765        let time_range = re_log_types::AbsoluteTimeRange::new(
766            re_log_types::TimeInt::new_temporal(123456789),
767            re_log_types::TimeInt::new_temporal(987654321),
768        );
769        let proto_time_range: crate::common::v1alpha1::TimeRange = time_range.into();
770        let time_range2: re_log_types::AbsoluteTimeRange = proto_time_range.into();
771        assert_eq!(time_range, time_range2);
772    }
773
774    #[test]
775    fn index_range_conversion() {
776        let time_range = re_log_types::AbsoluteTimeRange::new(
777            re_log_types::TimeInt::new_temporal(123456789),
778            re_log_types::TimeInt::new_temporal(987654321),
779        );
780        let proto_index_range: crate::common::v1alpha1::IndexRange = time_range.into();
781        let time_range2: re_log_types::AbsoluteTimeRange = proto_index_range.try_into().unwrap();
782        assert_eq!(time_range, time_range2);
783    }
784
785    #[test]
786    fn index_column_selector_conversion() {
787        let timeline = re_log_types::TimelineName::log_time();
788        let proto_index_column_selector: crate::common::v1alpha1::IndexColumnSelector =
789            crate::common::v1alpha1::IndexColumnSelector {
790                timeline: Some(timeline.into()),
791            };
792        let timeline2: re_log_types::TimelineName = proto_index_column_selector.try_into().unwrap();
793        assert_eq!(timeline, timeline2);
794    }
795
796    #[test]
797    fn application_id_conversion() {
798        let application_id = re_log_types::ApplicationId::from("test");
799        let proto_application_id: crate::common::v1alpha1::ApplicationId =
800            application_id.clone().into();
801        let application_id2: re_log_types::ApplicationId = proto_application_id.into();
802        assert_eq!(application_id, application_id2);
803    }
804
805    #[test]
806    fn store_kind_conversion() {
807        let store_kind = re_log_types::StoreKind::Recording;
808        let proto_store_kind: crate::common::v1alpha1::StoreKind = store_kind.into();
809        let store_kind2: re_log_types::StoreKind = proto_store_kind.into();
810        assert_eq!(store_kind, store_kind2);
811    }
812
813    #[test]
814    fn store_id_conversion() {
815        let store_id = re_log_types::StoreId::new(
816            re_log_types::StoreKind::Recording,
817            "test_app_id",
818            "test_recording",
819        );
820        let proto_store_id: crate::common::v1alpha1::StoreId = store_id.clone().into();
821        let store_id2: re_log_types::StoreId = proto_store_id.try_into().unwrap();
822        assert_eq!(store_id, store_id2);
823    }
824
825    #[test]
826    fn test_tuid_conversion() {
827        let tuid = re_tuid::Tuid::new();
828        let proto_tuid: crate::common::v1alpha1::Tuid = tuid.into();
829        let tuid2: re_tuid::Tuid = proto_tuid.try_into().unwrap();
830        assert_eq!(tuid, tuid2);
831    }
832}