re_types_core/
component_descriptor.rs1use std::borrow::Cow;
2
3use crate::{ArchetypeName, ComponentIdentifier, ComponentType};
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
11#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
12pub struct ComponentDescriptor {
13 pub archetype: Option<ArchetypeName>,
19
20 pub component: ComponentIdentifier,
24
25 pub component_type: Option<ComponentType>,
31}
32
33impl std::hash::Hash for ComponentDescriptor {
34 #[inline]
35 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
36 let Self {
37 archetype: archetype_name,
38 component,
39 component_type,
40 } = self;
41
42 let archetype_name = archetype_name.map_or(0, |v| v.hash());
43 let component = component.hash();
44 let component_type = component_type.map_or(0, |v| v.hash());
45
46 state.write_u64(archetype_name ^ component ^ component_type);
49 }
50}
51
52impl nohash_hasher::IsEnabled for ComponentDescriptor {}
53
54impl std::fmt::Display for ComponentDescriptor {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 f.write_str(self.display_name())
57 }
58}
59
60impl From<ComponentDescriptor> for Cow<'static, ComponentDescriptor> {
61 #[inline]
62 fn from(descr: ComponentDescriptor) -> Self {
63 Cow::Owned(descr)
64 }
65}
66
67impl<'d> From<&'d ComponentDescriptor> for Cow<'d, ComponentDescriptor> {
68 #[inline]
69 fn from(descr: &'d ComponentDescriptor) -> Self {
70 Cow::Borrowed(descr)
71 }
72}
73
74impl ComponentDescriptor {
75 #[inline]
76 #[track_caller]
77 pub fn sanity_check(&self) {
78 if let Some(component_type) = self.component_type {
79 component_type.sanity_check();
80 }
81 }
82
83 pub fn display_name(&self) -> &str {
85 self.sanity_check();
86 self.component.as_str()
87 }
88}
89
90impl re_byte_size::SizeBytes for ComponentDescriptor {
91 #[inline]
92 fn heap_size_bytes(&self) -> u64 {
93 let Self {
94 archetype: archetype_name,
95 component,
96 component_type,
97 } = self;
98 archetype_name.heap_size_bytes()
99 + component_type.heap_size_bytes()
100 + component.heap_size_bytes()
101 }
102}
103
104impl ComponentDescriptor {
105 pub fn partial(component: impl Into<ComponentIdentifier>) -> Self {
109 Self {
110 archetype: None,
111 component: component.into(),
112 component_type: None,
113 }
114 }
115
116 #[inline]
118 pub fn with_archetype(mut self, archetype_name: ArchetypeName) -> Self {
119 self.archetype = Some(archetype_name);
120 self
121 }
122
123 #[inline]
125 pub fn with_component_type(mut self, component_type: ComponentType) -> Self {
126 self.component_type = Some(component_type);
127 self
128 }
129
130 #[inline]
132 pub fn or_with_archetype(mut self, archetype_name: impl Fn() -> ArchetypeName) -> Self {
133 if self.archetype.is_none() {
134 self.archetype = Some(archetype_name());
135 }
136 self
137 }
138
139 #[inline]
141 pub fn or_with_component_type(
142 mut self,
143 component_type: impl FnOnce() -> ComponentType,
144 ) -> Self {
145 if self.component_type.is_none() {
146 self.component_type = Some(component_type());
147 }
148 self
149 }
150}
151
152const FIELD_METADATA_KEY_ARCHETYPE: &str = "rerun:archetype";
162
163const FIELD_METADATA_KEY_COMPONENT: &str = "rerun:component";
165
166const FIELD_METADATA_KEY_COMPONENT_TYPE: &str = "rerun:component_type";
168
169impl From<arrow::datatypes::Field> for ComponentDescriptor {
170 #[inline]
171 fn from(field: arrow::datatypes::Field) -> Self {
172 let md = field.metadata();
173
174 let descr = Self {
175 archetype: md
176 .get(FIELD_METADATA_KEY_ARCHETYPE)
177 .cloned()
178 .map(Into::into),
179 component: md.get(FIELD_METADATA_KEY_COMPONENT).cloned().unwrap_or_else(|| {
180 re_log::debug!("Missing metadata field {FIELD_METADATA_KEY_COMPONENT}, resorting to field name: {}", field.name());
181 field.name().to_string()
182 }).into(),
183 component_type: md
184 .get(FIELD_METADATA_KEY_COMPONENT_TYPE)
185 .cloned()
186 .map(Into::into),
187 };
188 descr.sanity_check();
189 descr
190 }
191}