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::{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)]
119pub struct VariantObject<'m, 'v> {
120 pub metadata: VariantMetadata<'m>,
121 pub value: &'v [u8],
122 header: VariantObjectHeader,
123 num_elements: u32,
124 first_field_offset_byte: u32,
125 first_value_byte: u32,
126 validated: bool,
127}
128
129#[cfg(target_pointer_width = "64")]
131const _: () = crate::utils::expect_size_of::<VariantObject>(64);
132
133#[cfg(target_pointer_width = "32")]
134const _: () = crate::utils::expect_size_of::<VariantObject>(44);
135
136impl<'m, 'v> VariantObject<'m, 'v> {
137 pub fn new(metadata: VariantMetadata<'m>, value: &'v [u8]) -> Self {
138 Self::try_new_with_shallow_validation(metadata, value).expect("Invalid variant object")
139 }
140
141 pub fn try_new(metadata: VariantMetadata<'m>, value: &'v [u8]) -> Result<Self, ArrowError> {
149 Self::try_new_with_shallow_validation(metadata, value)?.with_full_validation()
150 }
151
152 pub(crate) fn try_new_with_shallow_validation(
157 metadata: VariantMetadata<'m>,
158 value: &'v [u8],
159 ) -> Result<Self, ArrowError> {
160 let header_byte = first_byte_from_slice(value)?;
161 let header = VariantObjectHeader::try_new(header_byte)?;
162
163 let num_elements =
165 header
166 .num_elements_size
167 .unpack_u32_at_offset(value, NUM_HEADER_BYTES as _, 0)?;
168
169 let first_field_offset_byte = num_elements
172 .checked_mul(header.field_id_size())
173 .and_then(|n| n.checked_add(header.field_ids_start_byte()))
174 .ok_or_else(|| overflow_error("offset of variant object field offsets"))?;
175
176 let first_value_byte = num_elements
177 .checked_add(1)
178 .and_then(|n| n.checked_mul(header.field_offset_size()))
179 .and_then(|n| n.checked_add(first_field_offset_byte))
180 .ok_or_else(|| overflow_error("offset of variant object field values"))?;
181
182 let mut new_self = Self {
183 metadata,
184 value,
185 header,
186 num_elements,
187 first_field_offset_byte,
188 first_value_byte,
189 validated: false,
190 };
191
192 let last_offset = new_self
197 .get_offset(num_elements as _)?
198 .checked_add(first_value_byte)
199 .ok_or_else(|| overflow_error("variant object size"))?;
200 new_self.value = slice_from_slice(value, ..last_offset as _)?;
201 Ok(new_self)
202 }
203
204 pub fn is_fully_validated(&self) -> bool {
208 self.validated
209 }
210
211 pub fn with_full_validation(mut self) -> Result<Self, ArrowError> {
215 if !self.validated {
216 self.metadata = self.metadata.with_full_validation()?;
219
220 let field_id_buffer = slice_from_slice(
221 self.value,
222 self.header.field_ids_start_byte() as _..self.first_field_offset_byte as _,
223 )?;
224
225 let mut field_ids_iter =
226 map_bytes_to_offsets(field_id_buffer, self.header.field_id_size);
227
228 if self.metadata.is_sorted() {
230 let dictionary_size = self.metadata.len();
233
234 if let Some(mut current_id) = field_ids_iter.next() {
235 for next_id in field_ids_iter {
236 if current_id >= dictionary_size {
237 return Err(ArrowError::InvalidArgumentError(
238 "field id is not valid".to_string(),
239 ));
240 }
241
242 if next_id <= current_id {
243 return Err(ArrowError::InvalidArgumentError(
244 "field names not sorted".to_string(),
245 ));
246 }
247 current_id = next_id;
248 }
249
250 if current_id >= dictionary_size {
251 return Err(ArrowError::InvalidArgumentError(
252 "field id is not valid".to_string(),
253 ));
254 }
255 }
256 } else {
257 let mut current_field_name = match field_ids_iter.next() {
262 Some(field_id) => Some(self.metadata.get(field_id)?),
263 None => None,
264 };
265
266 for field_id in field_ids_iter {
267 let next_field_name = self.metadata.get(field_id)?;
268
269 if let Some(current_name) = current_field_name {
270 if next_field_name < current_name {
271 return Err(ArrowError::InvalidArgumentError(
272 "field names not sorted".to_string(),
273 ));
274 }
275 }
276 current_field_name = Some(next_field_name);
277 }
278 }
279
280 let field_offset_buffer = slice_from_slice(
282 self.value,
283 self.first_field_offset_byte as _..self.first_value_byte as _,
284 )?;
285 let num_offsets = field_offset_buffer.len() / self.header.field_offset_size() as usize;
286
287 let value_buffer = slice_from_slice(self.value, self.first_value_byte as _..)?;
288
289 map_bytes_to_offsets(field_offset_buffer, self.header.field_offset_size)
290 .take(num_offsets.saturating_sub(1))
291 .try_for_each(|offset| {
292 let value_bytes = slice_from_slice(value_buffer, offset..)?;
293 Variant::try_new_with_metadata(self.metadata.clone(), value_bytes)?;
294
295 Ok::<_, ArrowError>(())
296 })?;
297
298 self.validated = true;
299 }
300 Ok(self)
301 }
302
303 pub fn len(&self) -> usize {
305 self.num_elements as _
306 }
307
308 pub fn is_empty(&self) -> bool {
310 self.len() == 0
311 }
312
313 pub fn field(&self, i: usize) -> Option<Variant<'m, 'v>> {
321 (i < self.len()).then(|| {
322 self.try_field_with_shallow_validation(i)
323 .expect("Invalid object field value")
324 })
325 }
326
327 pub fn try_field(&self, i: usize) -> Result<Variant<'m, 'v>, ArrowError> {
329 self.try_field_with_shallow_validation(i)?
330 .with_full_validation()
331 }
332
333 fn try_field_with_shallow_validation(&self, i: usize) -> Result<Variant<'m, 'v>, ArrowError> {
336 let value_bytes = slice_from_slice(self.value, self.first_value_byte as _..)?;
337 let value_bytes = slice_from_slice(value_bytes, self.get_offset(i)? as _..)?;
338 Variant::try_new_with_metadata_and_shallow_validation(self.metadata.clone(), value_bytes)
339 }
340
341 fn get_offset(&self, i: usize) -> Result<u32, ArrowError> {
343 let byte_range = self.first_field_offset_byte as _..self.first_value_byte as _;
344 let field_offsets = slice_from_slice(self.value, byte_range)?;
345 self.header.field_offset_size.unpack_u32(field_offsets, i)
346 }
347
348 pub fn field_name(&self, i: usize) -> Option<&'m str> {
354 (i < self.len()).then(|| {
355 self.try_field_name(i)
356 .expect("Invalid variant object field name")
357 })
358 }
359
360 fn try_field_name(&self, i: usize) -> Result<&'m str, ArrowError> {
362 let byte_range = self.header.field_ids_start_byte() as _..self.first_field_offset_byte as _;
363 let field_id_bytes = slice_from_slice(self.value, byte_range)?;
364 let field_id = self.header.field_id_size.unpack_u32(field_id_bytes, i)?;
365 self.metadata.get(field_id as _)
366 }
367
368 pub fn iter(&self) -> impl Iterator<Item = (&'m str, Variant<'m, 'v>)> + '_ {
370 self.iter_try_with_shallow_validation()
371 .map(|result| result.expect("Invalid variant object field value"))
372 }
373
374 pub fn iter_try(
376 &self,
377 ) -> impl Iterator<Item = Result<(&'m str, Variant<'m, 'v>), ArrowError>> + '_ {
378 self.iter_try_with_shallow_validation().map(|result| {
379 let (name, value) = result?;
380 Ok((name, value.with_full_validation()?))
381 })
382 }
383
384 fn iter_try_with_shallow_validation(
387 &self,
388 ) -> impl Iterator<Item = Result<(&'m str, Variant<'m, 'v>), ArrowError>> + '_ {
389 (0..self.len()).map(|i| {
390 let field = self.try_field_with_shallow_validation(i)?;
391 Ok((self.try_field_name(i)?, field))
392 })
393 }
394
395 pub fn get(&self, name: &str) -> Option<Variant<'m, 'v>> {
399 let cmp = |i| Some(self.field_name(i)?.cmp(name));
405 let i = try_binary_search_range_by(0..self.len(), cmp)?.ok()?;
406 self.field(i)
407 }
408}
409
410impl<'m, 'v> PartialEq for VariantObject<'m, 'v> {
418 fn eq(&self, other: &Self) -> bool {
419 if self.num_elements != other.num_elements {
420 return false;
421 }
422
423 self.iter()
427 .zip(other.iter())
428 .all(|((name_a, value_a), (name_b, value_b))| name_a == name_b && value_a == value_b)
429 }
430}
431
432#[cfg(test)]
433mod tests {
434 use crate::VariantBuilder;
435
436 use super::*;
437
438 #[test]
439 fn test_variant_object_simple() {
440 let metadata_bytes = vec![
444 0b0001_0001,
445 3, 0, 6, 9, 13,
450 b'a',
451 b'c',
452 b't',
453 b'i',
454 b'v',
455 b'e',
456 b'a',
457 b'g',
458 b'e',
459 b'n',
460 b'a',
461 b'm',
462 b'e',
463 ];
464 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
465
466 let object_value = vec![
472 0x02, 3, 0, 1, 2,
476 0, 1, 3, 9, 0x04, 0x0C,
484 42, 0x15, b'h', b'e', b'l', b'l',
486 b'o', ];
488
489 let variant_obj = VariantObject::try_new(metadata, &object_value).unwrap();
490
491 assert_eq!(variant_obj.len(), 3);
493 assert!(!variant_obj.is_empty());
494
495 let active_field = variant_obj.get("active");
497 assert!(active_field.is_some());
498 assert_eq!(active_field.unwrap().as_boolean(), Some(true));
499
500 let age_field = variant_obj.get("age");
501 assert!(age_field.is_some());
502 assert_eq!(age_field.unwrap().as_int8(), Some(42));
503
504 let name_field = variant_obj.get("name");
505 assert!(name_field.is_some());
506 assert_eq!(name_field.unwrap().as_string(), Some("hello"));
507
508 let missing_field = variant_obj.get("missing");
510 assert!(missing_field.is_none());
511
512 let missing_field_name = variant_obj.field_name(3);
513 assert!(missing_field_name.is_none());
514
515 let missing_field_name = variant_obj.field_name(300);
516 assert!(missing_field_name.is_none());
517
518 let missing_field_value = variant_obj.field(3);
519 assert!(missing_field_value.is_none());
520
521 let missing_field_value = variant_obj.field(300);
522 assert!(missing_field_value.is_none());
523
524 let fields: Vec<_> = variant_obj.iter().collect();
526 assert_eq!(fields.len(), 3);
527
528 assert_eq!(fields[0].0, "active");
530 assert_eq!(fields[0].1.as_boolean(), Some(true));
531
532 assert_eq!(fields[1].0, "age");
533 assert_eq!(fields[1].1.as_int8(), Some(42));
534
535 assert_eq!(fields[2].0, "name");
536 assert_eq!(fields[2].1.as_string(), Some("hello"));
537
538 assert_eq!(variant_obj.field_name(0), Some("active"));
541 assert_eq!(variant_obj.field(0).unwrap().as_boolean(), Some(true));
542
543 assert_eq!(variant_obj.field_name(1), Some("age"));
544 assert_eq!(variant_obj.field(1).unwrap().as_int8(), Some(42));
545
546 assert_eq!(variant_obj.field_name(2), Some("name"));
547 assert_eq!(variant_obj.field(2).unwrap().as_string(), Some("hello"));
548 }
549
550 #[test]
551 fn test_variant_object_empty_fields() {
552 let mut builder = VariantBuilder::new();
553 builder.new_object().with_field("", 42).finish();
554 let (metadata, value) = builder.finish();
555
556 let variant = Variant::try_new(&metadata, &value).unwrap();
558 let variant_obj = variant.as_object().unwrap();
559 assert_eq!(variant_obj.len(), 1);
560 assert_eq!(variant_obj.get(""), Some(Variant::from(42)));
561 }
562
563 #[test]
564 fn test_variant_object_empty() {
565 let metadata_bytes = vec![
567 0x11, 0, 0, ];
571 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
572
573 let object_value = vec![
575 0x02, 0, 0, ];
580
581 let variant_obj = VariantObject::try_new(metadata, &object_value).unwrap();
582
583 assert_eq!(variant_obj.len(), 0);
585 assert!(variant_obj.is_empty());
586
587 let missing_field = variant_obj.get("anything");
589 assert!(missing_field.is_none());
590
591 let fields: Vec<_> = variant_obj.iter().collect();
593 assert_eq!(fields.len(), 0);
594 }
595
596 #[test]
597 fn test_variant_object_invalid_metadata_end_offset() {
598 let metadata_bytes = vec![
600 0b0001_0001, 2, 0, 3, 8, b'a',
606 b'g',
607 b'e',
608 b'n',
609 b'a',
610 b'm',
611 b'e',
612 ];
613 let err = VariantMetadata::try_new(&metadata_bytes);
614 let err = err.unwrap_err();
615 assert!(matches!(
616 err,
617 ArrowError::InvalidArgumentError(ref msg) if msg.contains("Tried to extract byte(s) ..13 from 12-byte buffer")
618 ));
619 }
620
621 #[test]
622 fn test_variant_object_invalid_end_offset() {
623 let metadata_bytes = vec![
625 0b0001_0001, 2, 0, 3, 7,
630 b'a',
631 b'g',
632 b'e',
633 b'n',
634 b'a',
635 b'm',
636 b'e',
637 ];
638 let metadata = VariantMetadata::try_new(&metadata_bytes).unwrap();
639
640 let object_value = vec![
645 0x02, 2, 0, 1,
649 0, 2, 9, 0x0C,
655 42, 0x15, b'h', b'e', b'l', b'l',
657 b'o', ];
659
660 let err = VariantObject::try_new(metadata, &object_value);
661 let err = err.unwrap_err();
662 assert!(matches!(
663 err,
664 ArrowError::InvalidArgumentError(ref msg) if msg.contains("Tried to extract byte(s) ..16 from 15-byte buffer")
665 ));
666 }
667
668 fn test_variant_object_with_count(count: i32, expected_field_id_size: OffsetSizeBytes) {
669 let field_names: Vec<_> = (0..count).map(|val| val.to_string()).collect();
670 let mut builder =
671 VariantBuilder::new().with_field_names(field_names.iter().map(|s| s.as_str()));
672
673 let mut obj = builder.new_object();
674
675 for i in 0..count {
676 obj.insert(&field_names[i as usize], i);
677 }
678
679 obj.finish();
680 let (metadata, value) = builder.finish();
681 let variant = Variant::new(&metadata, &value);
682
683 if let Variant::Object(obj) = variant {
684 assert_eq!(obj.len(), count as usize);
685
686 assert_eq!(obj.get(&field_names[0]).unwrap(), Variant::Int32(0));
687 assert_eq!(
688 obj.get(&field_names[(count - 1) as usize]).unwrap(),
689 Variant::Int32(count - 1)
690 );
691 assert_eq!(
692 obj.header.field_id_size, expected_field_id_size,
693 "Expected {}-byte field IDs, got {}-byte field IDs",
694 expected_field_id_size as usize, obj.header.field_id_size as usize
695 );
696 } else {
697 panic!("Expected object variant");
698 }
699 }
700
701 #[test]
702 fn test_variant_object_257_elements() {
703 test_variant_object_with_count((1 << 8) + 1, OffsetSizeBytes::Two); }
705
706 #[test]
707 fn test_variant_object_65537_elements() {
708 test_variant_object_with_count((1 << 16) + 1, OffsetSizeBytes::Three);
709 }
711
712 #[test]
721 fn test_variant_object_small_sizes_255_elements() {
722 test_variant_object_with_count(255, OffsetSizeBytes::One);
723 }
724
725 fn test_variant_object_with_large_data(
726 data_size_per_field: usize,
727 expected_field_offset_size: OffsetSizeBytes,
728 ) {
729 let num_fields = 20;
730 let mut builder = VariantBuilder::new();
731 let mut obj = builder.new_object();
732
733 let str_val = "a".repeat(data_size_per_field);
734
735 for val in 0..num_fields {
736 let key = format!("id_{val}");
737 obj.insert(&key, str_val.as_str());
738 }
739
740 obj.finish();
741 let (metadata, value) = builder.finish();
742 let variant = Variant::new(&metadata, &value);
743
744 if let Variant::Object(obj) = variant {
745 assert_eq!(obj.len(), num_fields);
746 assert_eq!(
747 obj.header.field_offset_size, expected_field_offset_size,
748 "Expected {}-byte field offsets, got {}-byte field offsets",
749 expected_field_offset_size as usize, obj.header.field_offset_size as usize
750 );
751 } else {
752 panic!("Expected object variant");
753 }
754 }
755
756 #[test]
757 fn test_variant_object_child_data_0_byte_offsets_minus_one() {
758 test_variant_object_with_large_data(10, OffsetSizeBytes::One);
759 }
760
761 #[test]
762 fn test_variant_object_256_bytes_child_data_3_byte_offsets() {
763 test_variant_object_with_large_data(256 + 1, OffsetSizeBytes::Two); }
765
766 #[test]
767 fn test_variant_object_16777216_bytes_child_data_4_byte_offsets() {
768 test_variant_object_with_large_data(65536 + 1, OffsetSizeBytes::Three); }
770
771 #[test]
772 fn test_variant_object_65535_bytes_child_data_2_byte_offsets() {
773 test_variant_object_with_large_data(16777216 + 1, OffsetSizeBytes::Four);
774 }
776
777 #[test]
778 fn test_objects_with_same_fields_are_equal() {
779 let mut b = VariantBuilder::new();
780 let mut o = b.new_object();
781
782 o.insert("b", ());
783 o.insert("c", ());
784 o.insert("a", ());
785
786 o.finish();
787
788 let (m, v) = b.finish();
789
790 let v1 = Variant::try_new(&m, &v).unwrap();
791 let v2 = Variant::try_new(&m, &v).unwrap();
792
793 assert_eq!(v1, v2);
794 }
795
796 #[test]
797 fn test_same_objects_with_different_builder_are_equal() {
798 let mut b = VariantBuilder::new();
799 let mut o = b.new_object();
800
801 o.insert("a", ());
802 o.insert("b", false);
803
804 o.finish();
805 let (m, v) = b.finish();
806
807 let v1 = Variant::try_new(&m, &v).unwrap();
808
809 let mut b = VariantBuilder::new();
810 let mut o = b.new_object();
811
812 o.insert("a", ());
813 o.insert("b", false);
814
815 o.finish();
816 let (m, v) = b.finish();
817
818 let v2 = Variant::try_new(&m, &v).unwrap();
819
820 assert_eq!(v1, v2);
821 }
822
823 #[test]
824 fn test_objects_with_different_values_are_not_equal() {
825 let mut b = VariantBuilder::new();
826 let mut o = b.new_object();
827
828 o.insert("a", ());
829 o.insert("b", 4.3);
830
831 o.finish();
832
833 let (m, v) = b.finish();
834
835 let v1 = Variant::try_new(&m, &v).unwrap();
836
837 let mut b = VariantBuilder::new();
839 let mut o = b.new_object();
840
841 o.insert("a", ());
842 let mut inner_o = o.new_object("b");
843 inner_o.insert("a", 3.3);
844 inner_o.finish();
845 o.finish();
846
847 let (m, v) = b.finish();
848
849 let v2 = Variant::try_new(&m, &v).unwrap();
850
851 let m1 = v1.metadata();
852 let m2 = v2.metadata();
853
854 assert_eq!(m1, m2);
856
857 assert_ne!(v1, v2);
859 }
860
861 #[test]
862 fn test_objects_with_different_field_names_are_not_equal() {
863 let mut b = VariantBuilder::new();
864 let mut o = b.new_object();
865
866 o.insert("a", ());
867 o.insert("b", 4.3);
868
869 o.finish();
870
871 let (m, v) = b.finish();
872
873 let v1 = Variant::try_new(&m, &v).unwrap();
874
875 let mut b = VariantBuilder::new();
877 let mut o = b.new_object();
878
879 o.insert("aardvark", ());
880 o.insert("barracuda", 3.3);
881
882 o.finish();
883
884 let (m, v) = b.finish();
885 let v2 = Variant::try_new(&m, &v).unwrap();
886
887 assert_ne!(v1, v2);
888 }
889
890 #[test]
891 fn test_objects_with_different_insertion_order_are_equal() {
892 let mut b = VariantBuilder::new();
893 let mut o = b.new_object();
894
895 o.insert("b", false);
896 o.insert("a", ());
897
898 o.finish();
899
900 let (m, v) = b.finish();
901
902 let v1 = Variant::try_new(&m, &v).unwrap();
903 assert!(!v1.metadata().is_sorted());
904
905 let mut b = VariantBuilder::new().with_field_names(["b", "a"]);
908 let mut o = b.new_object();
909
910 o.insert("a", ());
911 o.insert("b", false);
912
913 o.finish();
914
915 let (m, v) = b.finish();
916
917 let v2 = Variant::try_new(&m, &v).unwrap();
918
919 assert!(!v2.metadata().is_sorted());
921
922 assert_eq!(v1, v2);
923 }
924
925 #[test]
926 fn test_objects_with_differing_metadata_are_equal() {
927 let mut b = VariantBuilder::new();
928 let mut o = b.new_object();
929
930 o.insert("a", ());
931 o.insert("b", 4.3);
932
933 o.finish();
934
935 let (meta1, value1) = b.finish();
936
937 let v1 = Variant::try_new(&meta1, &value1).unwrap();
938 assert!(v1.metadata().is_sorted());
940
941 let mut b = VariantBuilder::new().with_field_names(["d", "c", "b", "a"]);
943 let mut o = b.new_object();
944
945 o.insert("b", 4.3);
946 o.insert("a", ());
947
948 o.finish();
949
950 let (meta2, value2) = b.finish();
951
952 let v2 = Variant::try_new(&meta2, &value2).unwrap();
953 assert!(!v2.metadata().is_sorted());
955
956 assert_ne!(v1.metadata(), v2.metadata());
958
959 assert_eq!(v1, v2);
961 }
962
963 #[test]
964 fn test_compare_object_with_unsorted_dictionary_vs_sorted_dictionary() {
965 let mut b = VariantBuilder::new();
967 let mut o = b.new_object();
968
969 o.insert("a", false);
970 o.insert("b", false);
971
972 o.finish();
973
974 let (m, v) = b.finish();
975
976 let v1 = Variant::try_new(&m, &v).unwrap();
977
978 let metadata_bytes = vec![
981 0b0000_0001,
982 3, 0, 1, 2, 3,
987 b'a',
988 b'b',
989 b'a',
990 ];
991 let m = VariantMetadata::try_new(&metadata_bytes).unwrap();
992 assert!(!m.is_sorted());
993
994 let v2 = Variant::new_with_metadata(m, &v);
995 assert_eq!(v1, v2);
996 }
997}