1use crate::decoder::{OffsetSizeBytes, map_bytes_to_offsets};
19use crate::utils::{
20 first_byte_from_slice, overflow_error, slice_from_slice, try_binary_search_range_by,
21};
22use crate::variant::{MAX_NESTING_DEPTH, Variant, VariantMetadata};
23
24use arrow_schema::ArrowError;
25
26const NUM_HEADER_BYTES: u32 = 1;
28
29#[derive(Debug, Clone, PartialEq)]
31pub(crate) struct VariantObjectHeader {
32 num_elements_size: OffsetSizeBytes,
33 field_id_size: OffsetSizeBytes,
34 field_offset_size: OffsetSizeBytes,
35}
36
37impl VariantObjectHeader {
38 const fn num_elements_size(&self) -> u32 {
40 self.num_elements_size as _
41 }
42 const fn field_id_size(&self) -> u32 {
43 self.field_id_size as _
44 }
45 const fn field_offset_size(&self) -> u32 {
46 self.field_offset_size as _
47 }
48
49 const fn field_ids_start_byte(&self) -> u32 {
51 NUM_HEADER_BYTES + self.num_elements_size()
52 }
53
54 pub(crate) fn try_new(header_byte: u8) -> Result<Self, ArrowError> {
55 let value_header = header_byte >> 2;
57 let field_offset_size_minus_one = value_header & 0x03; let field_id_size_minus_one = (value_header >> 2) & 0x03; let is_large = (value_header & 0x10) != 0; let num_elements_size = match is_large {
61 true => OffsetSizeBytes::Four,
62 false => OffsetSizeBytes::One,
63 };
64 Ok(Self {
65 num_elements_size,
66 field_id_size: OffsetSizeBytes::try_new(field_id_size_minus_one)?,
67 field_offset_size: OffsetSizeBytes::try_new(field_offset_size_minus_one)?,
68 })
69 }
70}
71
72#[derive(Debug, Clone)]
120pub struct VariantObject<'m, 'v> {
121 pub metadata: VariantMetadata<'m>,
122 pub value: &'v [u8],
123 header: VariantObjectHeader,
124 num_elements: u32,
125 first_field_offset_byte: u32,
126 first_value_byte: u32,
127 validated: bool,
128}
129
130#[cfg(target_pointer_width = "64")]
132const _: () = crate::utils::expect_size_of::<VariantObject>(64);
133
134#[cfg(target_pointer_width = "32")]
135const _: () = crate::utils::expect_size_of::<VariantObject>(44);
136
137impl<'m, 'v> VariantObject<'m, 'v> {
138 pub fn new(metadata: VariantMetadata<'m>, value: &'v [u8]) -> Self {
147 Self::try_new_with_shallow_validation(metadata, value).expect("Invalid variant object")
148 }
149
150 pub fn try_new(metadata: VariantMetadata<'m>, value: &'v [u8]) -> Result<Self, ArrowError> {
158 Self::try_new_with_shallow_validation(metadata, value)?.with_full_validation()
159 }
160
161 pub(crate) fn try_new_with_shallow_validation(
166 metadata: VariantMetadata<'m>,
167 value: &'v [u8],
168 ) -> Result<Self, ArrowError> {
169 let header_byte = first_byte_from_slice(value)?;
170 let header = VariantObjectHeader::try_new(header_byte)?;
171
172 let num_elements =
174 header
175 .num_elements_size
176 .unpack_u32_at_offset(value, NUM_HEADER_BYTES as _, 0)?;
177
178 let first_field_offset_byte = num_elements
181 .checked_mul(header.field_id_size())
182 .and_then(|n| n.checked_add(header.field_ids_start_byte()))
183 .ok_or_else(|| overflow_error("offset of variant object field offsets"))?;
184
185 let first_value_byte = num_elements
186 .checked_add(1)
187 .and_then(|n| n.checked_mul(header.field_offset_size()))
188 .and_then(|n| n.checked_add(first_field_offset_byte))
189 .ok_or_else(|| overflow_error("offset of variant object field values"))?;
190
191 let mut new_self = Self {
192 metadata,
193 value,
194 header,
195 num_elements,
196 first_field_offset_byte,
197 first_value_byte,
198 validated: false,
199 };
200
201 let last_offset = new_self
206 .get_offset(num_elements as _)?
207 .checked_add(first_value_byte)
208 .ok_or_else(|| overflow_error("variant object size"))?;
209 new_self.value = slice_from_slice(value, ..last_offset as _)?;
210 Ok(new_self)
211 }
212
213 pub fn is_fully_validated(&self) -> bool {
217 self.validated
218 }
219
220 pub fn with_full_validation(self) -> Result<Self, ArrowError> {
226 self.with_full_validation_at_depth(0)
227 }
228
229 pub(crate) fn with_full_validation_at_depth(
231 mut self,
232 depth: usize,
233 ) -> Result<Self, ArrowError> {
234 if !self.validated {
235 if depth >= MAX_NESTING_DEPTH {
236 return Err(ArrowError::InvalidArgumentError(format!(
237 "Variant nesting depth exceeds the maximum of {MAX_NESTING_DEPTH}"
238 )));
239 }
240
241 self.metadata = self.metadata.with_full_validation()?;
244
245 let field_id_buffer = slice_from_slice(
246 self.value,
247 self.header.field_ids_start_byte() as _..self.first_field_offset_byte as _,
248 )?;
249
250 let mut field_ids_iter =
251 map_bytes_to_offsets(field_id_buffer, self.header.field_id_size);
252
253 if self.metadata.is_sorted() {
255 let dictionary_size = self.metadata.len();
258
259 if let Some(mut current_id) = field_ids_iter.next() {
260 for next_id in field_ids_iter {
261 if current_id >= dictionary_size {
262 return Err(ArrowError::InvalidArgumentError(
263 "field id is not valid".to_string(),
264 ));
265 }
266
267 if next_id <= current_id {
268 return Err(ArrowError::InvalidArgumentError(
269 "field names not sorted".to_string(),
270 ));
271 }
272 current_id = next_id;
273 }
274
275 if current_id >= dictionary_size {
276 return Err(ArrowError::InvalidArgumentError(
277 "field id is not valid".to_string(),
278 ));
279 }
280 }
281 } else {
282 let mut current_field_name = match field_ids_iter.next() {
287 Some(field_id) => Some(self.metadata.get(field_id)?),
288 None => None,
289 };
290
291 for field_id in field_ids_iter {
292 let next_field_name = self.metadata.get(field_id)?;
293
294 if let Some(current_name) = current_field_name
297 && next_field_name <= current_name
298 {
299 return Err(ArrowError::InvalidArgumentError(
300 "field names not sorted".to_string(),
301 ));
302 }
303 current_field_name = Some(next_field_name);
304 }
305 }
306
307 let field_offset_buffer = slice_from_slice(
309 self.value,
310 self.first_field_offset_byte as _..self.first_value_byte as _,
311 )?;
312 let num_offsets = field_offset_buffer.len() / self.header.field_offset_size() as usize;
313
314 let value_buffer = slice_from_slice(self.value, self.first_value_byte as _..)?;
315
316 map_bytes_to_offsets(field_offset_buffer, self.header.field_offset_size)
317 .take(num_offsets.saturating_sub(1))
318 .try_for_each(|offset| {
319 let value_bytes = slice_from_slice(value_buffer, offset..)?;
320 Variant::try_new_with_metadata_at_depth(
321 self.metadata.clone(),
322 value_bytes,
323 depth + 1,
324 )?;
325
326 Ok::<_, ArrowError>(())
327 })?;
328
329 self.validated = true;
330 }
331 Ok(self)
332 }
333
334 pub fn len(&self) -> usize {
336 self.num_elements as _
337 }
338
339 pub fn is_empty(&self) -> bool {
341 self.len() == 0
342 }
343
344 pub fn field(&self, i: usize) -> Option<Variant<'m, 'v>> {
352 (i < self.len()).then(|| {
353 self.try_field_with_shallow_validation(i)
354 .expect("Invalid object field value")
355 })
356 }
357
358 pub fn try_field(&self, i: usize) -> Result<Variant<'m, 'v>, ArrowError> {
360 self.try_field_with_shallow_validation(i)?
361 .with_full_validation()
362 }
363
364 fn try_field_with_shallow_validation(&self, i: usize) -> Result<Variant<'m, 'v>, ArrowError> {
367 let value_bytes = slice_from_slice(self.value, self.first_value_byte as _..)?;
368 let value_bytes = slice_from_slice(value_bytes, self.get_offset(i)? as _..)?;
369 Variant::try_new_with_metadata_and_shallow_validation(self.metadata.clone(), value_bytes)
370 }
371
372 fn get_offset(&self, i: usize) -> Result<u32, ArrowError> {
374 let byte_range = self.first_field_offset_byte as _..self.first_value_byte as _;
375 let field_offsets = slice_from_slice(self.value, byte_range)?;
376 self.header.field_offset_size.unpack_u32(field_offsets, i)
377 }
378
379 pub fn field_name(&self, i: usize) -> Option<&'m str> {
385 (i < self.len()).then(|| {
386 self.try_field_name(i)
387 .expect("Invalid variant object field name")
388 })
389 }
390
391 fn try_field_name(&self, i: usize) -> Result<&'m str, ArrowError> {
393 let byte_range = self.header.field_ids_start_byte() as _..self.first_field_offset_byte as _;
394 let field_id_bytes = slice_from_slice(self.value, byte_range)?;
395 let field_id = self.header.field_id_size.unpack_u32(field_id_bytes, i)?;
396 self.metadata.get(field_id as _)
397 }
398
399 pub fn iter(&self) -> impl Iterator<Item = (&'m str, Variant<'m, 'v>)> + '_ {
405 self.iter_try_with_shallow_validation()
406 .map(|result| result.expect("Invalid variant object field value"))
407 }
408
409 pub fn iter_try(
411 &self,
412 ) -> impl Iterator<Item = Result<(&'m str, Variant<'m, 'v>), ArrowError>> + '_ {
413 self.iter_try_with_shallow_validation().map(|result| {
414 let (name, value) = result?;
415 Ok((name, value.with_full_validation()?))
416 })
417 }
418
419 fn iter_try_with_shallow_validation(
422 &self,
423 ) -> impl Iterator<Item = Result<(&'m str, Variant<'m, 'v>), ArrowError>> + '_ {
424 (0..self.len()).map(|i| {
425 let field = self.try_field_with_shallow_validation(i)?;
426 Ok((self.try_field_name(i)?, field))
427 })
428 }
429
430 pub fn get(&self, name: &str) -> Option<Variant<'m, 'v>> {
434 let cmp = |i| Some(self.field_name(i)?.cmp(name));
440 let i = try_binary_search_range_by(0..self.len(), cmp)?.ok()?;
441 self.field(i)
442 }
443}
444
445impl PartialEq for VariantObject<'_, '_> {
453 fn eq(&self, other: &Self) -> bool {
454 if self.num_elements != other.num_elements {
455 return false;
456 }
457
458 self.iter()
462 .zip(other.iter())
463 .all(|((name_a, value_a), (name_b, value_b))| name_a == name_b && value_a == value_b)
464 }
465}
466
467#[cfg(test)]
468mod tests {
469 use crate::VariantBuilder;
470
471 use super::*;
472
473 #[test]
474 fn test_variant_object_simple() {
475 let metadata_bytes = vec![
479 0b0001_0001,
480 3, 0, 6, 9, 13,
485 b'a',
486 b'c',
487 b't',
488 b'i',
489 b'v',
490 b'e',
491 b'a',
492 b'g',
493 b'e',
494 b'n',
495 b'a',
496 b'm',
497 b'e',
498 ];
499 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
500
501 let object_value = vec![
507 0x02, 3, 0, 1, 2,
511 0, 1, 3, 9, 0x04, 0x0C,
519 42, 0x15, b'h', b'e', b'l', b'l',
521 b'o', ];
523
524 let variant_obj = VariantObject::try_new(metadata, &object_value).unwrap();
525
526 assert_eq!(variant_obj.len(), 3);
528 assert!(!variant_obj.is_empty());
529
530 let active_field = variant_obj.get("active");
532 assert!(active_field.is_some());
533 assert_eq!(active_field.unwrap().as_boolean(), Some(true));
534
535 let age_field = variant_obj.get("age");
536 assert!(age_field.is_some());
537 assert_eq!(age_field.unwrap().as_int8(), Some(42));
538
539 let name_field = variant_obj.get("name");
540 assert!(name_field.is_some());
541 assert_eq!(name_field.unwrap().as_string(), Some("hello"));
542
543 let missing_field = variant_obj.get("missing");
545 assert!(missing_field.is_none());
546
547 let missing_field_name = variant_obj.field_name(3);
548 assert!(missing_field_name.is_none());
549
550 let missing_field_name = variant_obj.field_name(300);
551 assert!(missing_field_name.is_none());
552
553 let missing_field_value = variant_obj.field(3);
554 assert!(missing_field_value.is_none());
555
556 let missing_field_value = variant_obj.field(300);
557 assert!(missing_field_value.is_none());
558
559 let fields: Vec<_> = variant_obj.iter().collect();
561 assert_eq!(fields.len(), 3);
562
563 assert_eq!(fields[0].0, "active");
565 assert_eq!(fields[0].1.as_boolean(), Some(true));
566
567 assert_eq!(fields[1].0, "age");
568 assert_eq!(fields[1].1.as_int8(), Some(42));
569
570 assert_eq!(fields[2].0, "name");
571 assert_eq!(fields[2].1.as_string(), Some("hello"));
572
573 assert_eq!(variant_obj.field_name(0), Some("active"));
576 assert_eq!(variant_obj.field(0).unwrap().as_boolean(), Some(true));
577
578 assert_eq!(variant_obj.field_name(1), Some("age"));
579 assert_eq!(variant_obj.field(1).unwrap().as_int8(), Some(42));
580
581 assert_eq!(variant_obj.field_name(2), Some("name"));
582 assert_eq!(variant_obj.field(2).unwrap().as_string(), Some("hello"));
583 }
584
585 #[test]
586 fn test_variant_object_empty_fields() {
587 let mut builder = VariantBuilder::new();
588 builder.new_object().with_field("", 42).finish();
589 let (metadata, value) = builder.finish();
590
591 let variant = Variant::try_new(&metadata, &value).unwrap();
593 let variant_obj = variant.as_object().unwrap();
594 assert_eq!(variant_obj.len(), 1);
595 assert_eq!(variant_obj.get(""), Some(Variant::from(42)));
596 }
597
598 #[test]
599 fn test_variant_object_empty() {
600 let metadata_bytes = vec![
602 0x11, 0, 0, ];
606 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
607
608 let object_value = vec![
610 0x02, 0, 0, ];
615
616 let variant_obj = VariantObject::try_new(metadata, &object_value).unwrap();
617
618 assert_eq!(variant_obj.len(), 0);
620 assert!(variant_obj.is_empty());
621
622 let missing_field = variant_obj.get("anything");
624 assert!(missing_field.is_none());
625
626 let fields: Vec<_> = variant_obj.iter().collect();
628 assert_eq!(fields.len(), 0);
629 }
630
631 #[test]
632 fn test_variant_object_invalid_metadata_end_offset() {
633 let metadata_bytes = vec![
635 0b0001_0001, 2, 0, 3, 8, b'a',
641 b'g',
642 b'e',
643 b'n',
644 b'a',
645 b'm',
646 b'e',
647 ];
648 let err = VariantMetadata::try_new(&metadata_bytes);
649 let err = err.unwrap_err();
650 assert!(matches!(
651 err,
652 ArrowError::InvalidArgumentError(ref msg) if msg.contains("Tried to extract byte(s) ..13 from 12-byte buffer")
653 ));
654 }
655
656 #[test]
657 fn test_variant_object_invalid_end_offset() {
658 let metadata_bytes = vec![
660 0b0001_0001, 2, 0, 3, 7,
665 b'a',
666 b'g',
667 b'e',
668 b'n',
669 b'a',
670 b'm',
671 b'e',
672 ];
673 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
674
675 let object_value = vec![
680 0x02, 2, 0, 1,
684 0, 2, 9, 0x0C,
690 42, 0x15, b'h', b'e', b'l', b'l',
692 b'o', ];
694
695 let err = VariantObject::try_new(metadata, &object_value);
696 let err = err.unwrap_err();
697 assert!(matches!(
698 err,
699 ArrowError::InvalidArgumentError(ref msg) if msg.contains("Tried to extract byte(s) ..16 from 15-byte buffer")
700 ));
701 }
702
703 fn test_variant_object_with_count(count: i32, expected_field_id_size: OffsetSizeBytes) {
704 let field_names: Vec<_> = (0..count).map(|val| val.to_string()).collect();
705 let mut builder =
706 VariantBuilder::new().with_field_names(field_names.iter().map(|s| s.as_str()));
707
708 let mut obj = builder.new_object();
709
710 for i in 0..count {
711 obj.insert(&field_names[i as usize], i);
712 }
713
714 obj.finish();
715 let (metadata, value) = builder.finish();
716 let variant = Variant::new(&metadata, &value);
717
718 if let Variant::Object(obj) = variant {
719 assert_eq!(obj.len(), count as usize);
720
721 assert_eq!(obj.get(&field_names[0]).unwrap(), Variant::Int32(0));
722 assert_eq!(
723 obj.get(&field_names[(count - 1) as usize]).unwrap(),
724 Variant::Int32(count - 1)
725 );
726 assert_eq!(
727 obj.header.field_id_size, expected_field_id_size,
728 "Expected {}-byte field IDs, got {}-byte field IDs",
729 expected_field_id_size as usize, obj.header.field_id_size as usize
730 );
731 } else {
732 panic!("Expected object variant");
733 }
734 }
735
736 #[test]
737 fn test_variant_object_257_elements() {
738 test_variant_object_with_count((1 << 8) + 1, OffsetSizeBytes::Two); }
740
741 #[test]
742 fn test_variant_object_65537_elements() {
743 test_variant_object_with_count((1 << 16) + 1, OffsetSizeBytes::Three);
744 }
746
747 #[test]
756 fn test_variant_object_small_sizes_255_elements() {
757 test_variant_object_with_count(255, OffsetSizeBytes::One);
758 }
759
760 fn test_variant_object_with_large_data(
761 data_size_per_field: usize,
762 expected_field_offset_size: OffsetSizeBytes,
763 ) {
764 let num_fields = 20;
765 let mut builder = VariantBuilder::new();
766 let mut obj = builder.new_object();
767
768 let str_val = "a".repeat(data_size_per_field);
769
770 for val in 0..num_fields {
771 let key = format!("id_{val}");
772 obj.insert(&key, str_val.as_str());
773 }
774
775 obj.finish();
776 let (metadata, value) = builder.finish();
777 let variant = Variant::new(&metadata, &value);
778
779 if let Variant::Object(obj) = variant {
780 assert_eq!(obj.len(), num_fields);
781 assert_eq!(
782 obj.header.field_offset_size, expected_field_offset_size,
783 "Expected {}-byte field offsets, got {}-byte field offsets",
784 expected_field_offset_size as usize, obj.header.field_offset_size as usize
785 );
786 } else {
787 panic!("Expected object variant");
788 }
789 }
790
791 #[test]
792 fn test_variant_object_child_data_0_byte_offsets_minus_one() {
793 test_variant_object_with_large_data(10, OffsetSizeBytes::One);
794 }
795
796 #[test]
797 fn test_variant_object_256_bytes_child_data_3_byte_offsets() {
798 test_variant_object_with_large_data(256 + 1, OffsetSizeBytes::Two); }
800
801 #[test]
802 fn test_variant_object_16777216_bytes_child_data_4_byte_offsets() {
803 test_variant_object_with_large_data(65536 + 1, OffsetSizeBytes::Three); }
805
806 #[test]
807 fn test_variant_object_65535_bytes_child_data_2_byte_offsets() {
808 test_variant_object_with_large_data(16777216 + 1, OffsetSizeBytes::Four);
809 }
811
812 #[test]
813 fn test_objects_with_same_fields_are_equal() {
814 let mut b = VariantBuilder::new();
815 let mut o = b.new_object();
816
817 o.insert("b", ());
818 o.insert("c", ());
819 o.insert("a", ());
820
821 o.finish();
822
823 let (m, v) = b.finish();
824
825 let v1 = Variant::try_new(&m, &v).unwrap();
826 let v2 = Variant::try_new(&m, &v).unwrap();
827
828 assert_eq!(v1, v2);
829 }
830
831 #[test]
832 fn test_same_objects_with_different_builder_are_equal() {
833 let mut b = VariantBuilder::new();
834 let mut o = b.new_object();
835
836 o.insert("a", ());
837 o.insert("b", false);
838
839 o.finish();
840 let (m, v) = b.finish();
841
842 let v1 = Variant::try_new(&m, &v).unwrap();
843
844 let mut b = VariantBuilder::new();
845 let mut o = b.new_object();
846
847 o.insert("a", ());
848 o.insert("b", false);
849
850 o.finish();
851 let (m, v) = b.finish();
852
853 let v2 = Variant::try_new(&m, &v).unwrap();
854
855 assert_eq!(v1, v2);
856 }
857
858 #[test]
859 fn test_objects_with_different_values_are_not_equal() {
860 let mut b = VariantBuilder::new();
861 let mut o = b.new_object();
862
863 o.insert("a", ());
864 o.insert("b", 4.3);
865
866 o.finish();
867
868 let (m, v) = b.finish();
869
870 let v1 = Variant::try_new(&m, &v).unwrap();
871
872 let mut b = VariantBuilder::new();
874 let mut o = b.new_object();
875
876 o.insert("a", ());
877 let mut inner_o = o.new_object("b");
878 inner_o.insert("a", 3.3);
879 inner_o.finish();
880 o.finish();
881
882 let (m, v) = b.finish();
883
884 let v2 = Variant::try_new(&m, &v).unwrap();
885
886 let m1 = v1.metadata();
887 let m2 = v2.metadata();
888
889 assert_eq!(m1, m2);
891
892 assert_ne!(v1, v2);
894 }
895
896 #[test]
897 fn test_objects_with_different_field_names_are_not_equal() {
898 let mut b = VariantBuilder::new();
899 let mut o = b.new_object();
900
901 o.insert("a", ());
902 o.insert("b", 4.3);
903
904 o.finish();
905
906 let (m, v) = b.finish();
907
908 let v1 = Variant::try_new(&m, &v).unwrap();
909
910 let mut b = VariantBuilder::new();
912 let mut o = b.new_object();
913
914 o.insert("aardvark", ());
915 o.insert("barracuda", 3.3);
916
917 o.finish();
918
919 let (m, v) = b.finish();
920 let v2 = Variant::try_new(&m, &v).unwrap();
921
922 assert_ne!(v1, v2);
923 }
924
925 #[test]
926 fn test_objects_with_different_insertion_order_are_equal() {
927 let mut b = VariantBuilder::new();
928 let mut o = b.new_object();
929
930 o.insert("b", false);
931 o.insert("a", ());
932
933 o.finish();
934
935 let (m, v) = b.finish();
936
937 let v1 = Variant::try_new(&m, &v).unwrap();
938 assert!(!v1.metadata().is_sorted());
939
940 let mut b = VariantBuilder::new().with_field_names(["b", "a"]);
943 let mut o = b.new_object();
944
945 o.insert("a", ());
946 o.insert("b", false);
947
948 o.finish();
949
950 let (m, v) = b.finish();
951
952 let v2 = Variant::try_new(&m, &v).unwrap();
953
954 assert!(!v2.metadata().is_sorted());
956
957 assert_eq!(v1, v2);
958 }
959
960 #[test]
961 fn test_objects_with_differing_metadata_are_equal() {
962 let mut b = VariantBuilder::new();
963 let mut o = b.new_object();
964
965 o.insert("a", ());
966 o.insert("b", 4.3);
967
968 o.finish();
969
970 let (meta1, value1) = b.finish();
971
972 let v1 = Variant::try_new(&meta1, &value1).unwrap();
973 assert!(v1.metadata().is_sorted());
975
976 let mut b = VariantBuilder::new().with_field_names(["d", "c", "b", "a"]);
978 let mut o = b.new_object();
979
980 o.insert("b", 4.3);
981 o.insert("a", ());
982
983 o.finish();
984
985 let (meta2, value2) = b.finish();
986
987 let v2 = Variant::try_new(&meta2, &value2).unwrap();
988 assert!(!v2.metadata().is_sorted());
990
991 assert_ne!(v1.metadata(), v2.metadata());
993
994 assert_eq!(v1, v2);
996 }
997
998 #[test]
999 fn test_compare_object_with_unsorted_dictionary_vs_sorted_dictionary() {
1000 let mut b = VariantBuilder::new();
1002 let mut o = b.new_object();
1003
1004 o.insert("a", false);
1005 o.insert("b", false);
1006
1007 o.finish();
1008
1009 let (m, v) = b.finish();
1010
1011 let v1 = Variant::try_new(&m, &v).unwrap();
1012
1013 let metadata_bytes = vec![
1016 0b0000_0001,
1017 3, 0, 1, 2, 3,
1022 b'a',
1023 b'b',
1024 b'a',
1025 ];
1026 let m = VariantMetadata::try_new(&metadata_bytes).unwrap();
1027 assert!(!m.is_sorted());
1028
1029 let v2 = Variant::new_with_metadata(m, &v);
1030 assert_eq!(v1, v2);
1031 }
1032
1033 #[test]
1034 fn test_object_rejects_duplicate_field_names() {
1035 let metadata_bytes = vec![
1038 0b0000_0001,
1039 2, 0, 1, 2,
1043 b'a',
1044 b'a',
1045 ];
1046 assert!(
1047 !VariantMetadata::try_new(&metadata_bytes)
1048 .unwrap()
1049 .is_sorted()
1050 );
1051
1052 let value_bytes = vec![
1053 0b0000_0010, 2, 0, 1, 0,
1058 1,
1059 2, 0b0000_1100, 0b0000_1000, ];
1063 let err = Variant::try_new(&metadata_bytes, &value_bytes).unwrap_err();
1064 assert!(
1065 matches!(err, ArrowError::InvalidArgumentError(_)),
1066 "unexpected error: {err:?}"
1067 );
1068 }
1069
1070 fn make_nested_objects(depth: usize) -> Vec<u8> {
1072 let mut value = vec![0u8]; for _ in 0..depth {
1074 let mut outer = vec![0b0000_1110, 1, 0];
1076 outer.extend_from_slice(&0u32.to_le_bytes());
1077 outer.extend_from_slice(&(value.len() as u32).to_le_bytes());
1078 outer.append(&mut value);
1079 value = outer;
1080 }
1081 value
1082 }
1083
1084 #[test]
1085 fn test_variant_object_nesting_depth_limit() {
1086 let metadata = [0b0000_0001, 1, 0, 1, b'a']; let value = make_nested_objects(MAX_NESTING_DEPTH);
1089 Variant::try_new(&metadata, &value).unwrap();
1090
1091 let value = make_nested_objects(MAX_NESTING_DEPTH + 1);
1093 let err = Variant::try_new(&metadata, &value).unwrap_err();
1094 assert!(
1095 err.to_string().contains("nesting depth exceeds"),
1096 "unexpected error: {err}"
1097 );
1098 }
1099}