1#![allow(unused_imports)]
5#![allow(unused_parens)]
6#![allow(clippy::clone_on_copy)]
7#![allow(clippy::cloned_instead_of_copied)]
8#![allow(clippy::map_flatten)]
9#![allow(clippy::needless_question_mark)]
10#![allow(clippy::new_without_default)]
11#![allow(clippy::redundant_closure)]
12#![allow(clippy::too_many_arguments)]
13#![allow(clippy::too_many_lines)]
14
15use ::re_types_core::try_serialize_field;
16use ::re_types_core::SerializationResult;
17use ::re_types_core::{ComponentBatch as _, SerializedComponentBatch};
18use ::re_types_core::{ComponentDescriptor, ComponentName};
19use ::re_types_core::{DeserializationError, DeserializationResult};
20
21#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
23pub struct Utf8Pair {
24 pub first: crate::datatypes::Utf8,
26
27 pub second: crate::datatypes::Utf8,
29}
30
31::re_types_core::macros::impl_into_cow!(Utf8Pair);
32
33impl ::re_types_core::Loggable for Utf8Pair {
34 #[inline]
35 fn arrow_datatype() -> arrow::datatypes::DataType {
36 #![allow(clippy::wildcard_imports)]
37 use arrow::datatypes::*;
38 DataType::Struct(Fields::from(vec![
39 Field::new("first", <crate::datatypes::Utf8>::arrow_datatype(), false),
40 Field::new("second", <crate::datatypes::Utf8>::arrow_datatype(), false),
41 ]))
42 }
43
44 fn to_arrow_opt<'a>(
45 data: impl IntoIterator<Item = Option<impl Into<::std::borrow::Cow<'a, Self>>>>,
46 ) -> SerializationResult<arrow::array::ArrayRef>
47 where
48 Self: Clone + 'a,
49 {
50 #![allow(clippy::wildcard_imports)]
51 #![allow(clippy::manual_is_variant_and)]
52 use ::re_types_core::{arrow_helpers::as_array_ref, Loggable as _, ResultExt as _};
53 use arrow::{array::*, buffer::*, datatypes::*};
54 Ok({
55 let fields = Fields::from(vec![
56 Field::new("first", <crate::datatypes::Utf8>::arrow_datatype(), false),
57 Field::new("second", <crate::datatypes::Utf8>::arrow_datatype(), false),
58 ]);
59 let (somes, data): (Vec<_>, Vec<_>) = data
60 .into_iter()
61 .map(|datum| {
62 let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into);
63 (datum.is_some(), datum)
64 })
65 .unzip();
66 let validity: Option<arrow::buffer::NullBuffer> = {
67 let any_nones = somes.iter().any(|some| !*some);
68 any_nones.then(|| somes.into())
69 };
70 as_array_ref(StructArray::new(
71 fields,
72 vec![
73 {
74 let (somes, first): (Vec<_>, Vec<_>) = data
75 .iter()
76 .map(|datum| {
77 let datum = datum.as_ref().map(|datum| datum.first.clone());
78 (datum.is_some(), datum)
79 })
80 .unzip();
81 let first_validity: Option<arrow::buffer::NullBuffer> = {
82 let any_nones = somes.iter().any(|some| !*some);
83 any_nones.then(|| somes.into())
84 };
85 {
86 let offsets = arrow::buffer::OffsetBuffer::<i32>::from_lengths(
87 first.iter().map(|opt| {
88 opt.as_ref().map(|datum| datum.0.len()).unwrap_or_default()
89 }),
90 );
91 #[allow(clippy::unwrap_used)]
92 let capacity = offsets.last().copied().unwrap() as usize;
93 let mut buffer_builder =
94 arrow::array::builder::BufferBuilder::<u8>::new(capacity);
95 for data in first.iter().flatten() {
96 buffer_builder.append_slice(data.0.as_bytes());
97 }
98 let inner_data: arrow::buffer::Buffer = buffer_builder.finish();
99
100 #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
101 as_array_ref(unsafe {
102 StringArray::new_unchecked(offsets, inner_data, first_validity)
103 })
104 }
105 },
106 {
107 let (somes, second): (Vec<_>, Vec<_>) = data
108 .iter()
109 .map(|datum| {
110 let datum = datum.as_ref().map(|datum| datum.second.clone());
111 (datum.is_some(), datum)
112 })
113 .unzip();
114 let second_validity: Option<arrow::buffer::NullBuffer> = {
115 let any_nones = somes.iter().any(|some| !*some);
116 any_nones.then(|| somes.into())
117 };
118 {
119 let offsets = arrow::buffer::OffsetBuffer::<i32>::from_lengths(
120 second.iter().map(|opt| {
121 opt.as_ref().map(|datum| datum.0.len()).unwrap_or_default()
122 }),
123 );
124
125 #[allow(clippy::unwrap_used)]
126 let capacity = offsets.last().copied().unwrap() as usize;
127 let mut buffer_builder =
128 arrow::array::builder::BufferBuilder::<u8>::new(capacity);
129 for data in second.iter().flatten() {
130 buffer_builder.append_slice(data.0.as_bytes());
131 }
132 let inner_data: arrow::buffer::Buffer = buffer_builder.finish();
133
134 #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
135 as_array_ref(unsafe {
136 StringArray::new_unchecked(offsets, inner_data, second_validity)
137 })
138 }
139 },
140 ],
141 validity,
142 ))
143 })
144 }
145
146 fn from_arrow_opt(
147 arrow_data: &dyn arrow::array::Array,
148 ) -> DeserializationResult<Vec<Option<Self>>>
149 where
150 Self: Sized,
151 {
152 #![allow(clippy::wildcard_imports)]
153 use ::re_types_core::{arrow_zip_validity::ZipValidity, Loggable as _, ResultExt as _};
154 use arrow::{array::*, buffer::*, datatypes::*};
155 Ok({
156 let arrow_data = arrow_data
157 .as_any()
158 .downcast_ref::<arrow::array::StructArray>()
159 .ok_or_else(|| {
160 let expected = Self::arrow_datatype();
161 let actual = arrow_data.data_type().clone();
162 DeserializationError::datatype_mismatch(expected, actual)
163 })
164 .with_context("rerun.datatypes.Utf8Pair")?;
165 if arrow_data.is_empty() {
166 Vec::new()
167 } else {
168 let (arrow_data_fields, arrow_data_arrays) =
169 (arrow_data.fields(), arrow_data.columns());
170 let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data_fields
171 .iter()
172 .map(|field| field.name().as_str())
173 .zip(arrow_data_arrays)
174 .collect();
175 let first = {
176 if !arrays_by_name.contains_key("first") {
177 return Err(DeserializationError::missing_struct_field(
178 Self::arrow_datatype(),
179 "first",
180 ))
181 .with_context("rerun.datatypes.Utf8Pair");
182 }
183 let arrow_data = &**arrays_by_name["first"];
184 {
185 let arrow_data = arrow_data
186 .as_any()
187 .downcast_ref::<StringArray>()
188 .ok_or_else(|| {
189 let expected = DataType::Utf8;
190 let actual = arrow_data.data_type().clone();
191 DeserializationError::datatype_mismatch(expected, actual)
192 })
193 .with_context("rerun.datatypes.Utf8Pair#first")?;
194 let arrow_data_buf = arrow_data.values();
195 let offsets = arrow_data.offsets();
196 ZipValidity::new_with_validity(offsets.windows(2), arrow_data.nulls())
197 .map(|elem| {
198 elem.map(|window| {
199 let start = window[0] as usize;
200 let end = window[1] as usize;
201 let len = end - start;
202 if arrow_data_buf.len() < end {
203 return Err(DeserializationError::offset_slice_oob(
204 (start, end),
205 arrow_data_buf.len(),
206 ));
207 }
208
209 #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
210 let data = arrow_data_buf.slice_with_length(start, len);
211 Ok(data)
212 })
213 .transpose()
214 })
215 .map(|res_or_opt| {
216 res_or_opt.map(|res_or_opt| {
217 res_or_opt.map(|v| {
218 crate::datatypes::Utf8(::re_types_core::ArrowString::from(
219 v,
220 ))
221 })
222 })
223 })
224 .collect::<DeserializationResult<Vec<Option<_>>>>()
225 .with_context("rerun.datatypes.Utf8Pair#first")?
226 .into_iter()
227 }
228 };
229 let second = {
230 if !arrays_by_name.contains_key("second") {
231 return Err(DeserializationError::missing_struct_field(
232 Self::arrow_datatype(),
233 "second",
234 ))
235 .with_context("rerun.datatypes.Utf8Pair");
236 }
237 let arrow_data = &**arrays_by_name["second"];
238 {
239 let arrow_data = arrow_data
240 .as_any()
241 .downcast_ref::<StringArray>()
242 .ok_or_else(|| {
243 let expected = DataType::Utf8;
244 let actual = arrow_data.data_type().clone();
245 DeserializationError::datatype_mismatch(expected, actual)
246 })
247 .with_context("rerun.datatypes.Utf8Pair#second")?;
248 let arrow_data_buf = arrow_data.values();
249 let offsets = arrow_data.offsets();
250 ZipValidity::new_with_validity(offsets.windows(2), arrow_data.nulls())
251 .map(|elem| {
252 elem.map(|window| {
253 let start = window[0] as usize;
254 let end = window[1] as usize;
255 let len = end - start;
256 if arrow_data_buf.len() < end {
257 return Err(DeserializationError::offset_slice_oob(
258 (start, end),
259 arrow_data_buf.len(),
260 ));
261 }
262
263 #[allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
264 let data = arrow_data_buf.slice_with_length(start, len);
265 Ok(data)
266 })
267 .transpose()
268 })
269 .map(|res_or_opt| {
270 res_or_opt.map(|res_or_opt| {
271 res_or_opt.map(|v| {
272 crate::datatypes::Utf8(::re_types_core::ArrowString::from(
273 v,
274 ))
275 })
276 })
277 })
278 .collect::<DeserializationResult<Vec<Option<_>>>>()
279 .with_context("rerun.datatypes.Utf8Pair#second")?
280 .into_iter()
281 }
282 };
283 ZipValidity::new_with_validity(
284 ::itertools::izip!(first, second),
285 arrow_data.nulls(),
286 )
287 .map(|opt| {
288 opt.map(|(first, second)| {
289 Ok(Self {
290 first: first
291 .ok_or_else(DeserializationError::missing_data)
292 .with_context("rerun.datatypes.Utf8Pair#first")?,
293 second: second
294 .ok_or_else(DeserializationError::missing_data)
295 .with_context("rerun.datatypes.Utf8Pair#second")?,
296 })
297 })
298 .transpose()
299 })
300 .collect::<DeserializationResult<Vec<_>>>()
301 .with_context("rerun.datatypes.Utf8Pair")?
302 }
303 })
304 }
305}
306
307impl ::re_byte_size::SizeBytes for Utf8Pair {
308 #[inline]
309 fn heap_size_bytes(&self) -> u64 {
310 self.first.heap_size_bytes() + self.second.heap_size_bytes()
311 }
312
313 #[inline]
314 fn is_pod() -> bool {
315 <crate::datatypes::Utf8>::is_pod() && <crate::datatypes::Utf8>::is_pod()
316 }
317}