1use std::ops::Deref;
19use std::sync::Arc;
20
21use crate::{ArrowError, DataType, Field, FieldRef};
22
23#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59#[cfg_attr(feature = "serde", serde(transparent))]
60pub struct Fields(Arc<[FieldRef]>);
61
62impl std::fmt::Debug for Fields {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 self.0.as_ref().fmt(f)
65 }
66}
67
68impl Fields {
69 pub fn empty() -> Self {
71 Self(Arc::new([]))
72 }
73
74 pub fn size(&self) -> usize {
76 self.iter()
77 .map(|field| field.size() + std::mem::size_of::<FieldRef>())
78 .sum()
79 }
80
81 pub fn find(&self, name: &str) -> Option<(usize, &FieldRef)> {
83 self.0.iter().enumerate().find(|(_, b)| b.name() == name)
84 }
85
86 pub fn contains(&self, other: &Fields) -> bool {
93 if Arc::ptr_eq(&self.0, &other.0) {
94 return true;
95 }
96 self.len() == other.len()
97 && self
98 .iter()
99 .zip(other.iter())
100 .all(|(a, b)| Arc::ptr_eq(a, b) || a.contains(b))
101 }
102
103 pub fn filter_leaves<F: FnMut(usize, &FieldRef) -> bool>(&self, mut filter: F) -> Self {
140 self.try_filter_leaves(|idx, field| Ok(filter(idx, field)))
141 .unwrap()
142 }
143
144 pub fn try_filter_leaves<F: FnMut(usize, &FieldRef) -> Result<bool, ArrowError>>(
149 &self,
150 mut filter: F,
151 ) -> Result<Self, ArrowError> {
152 fn filter_field<F: FnMut(&FieldRef) -> Result<bool, ArrowError>>(
153 f: &FieldRef,
154 filter: &mut F,
155 ) -> Result<Option<FieldRef>, ArrowError> {
156 use DataType::*;
157
158 let v = match f.data_type() {
159 Dictionary(_, v) => v.as_ref(), RunEndEncoded(_, v) => v.data_type(), d => d,
162 };
163 let d = match v {
164 List(child) => {
165 let fields = filter_field(child, filter)?;
166 if let Some(fields) = fields {
167 List(fields)
168 } else {
169 return Ok(None);
170 }
171 }
172 LargeList(child) => {
173 let fields = filter_field(child, filter)?;
174 if let Some(fields) = fields {
175 LargeList(fields)
176 } else {
177 return Ok(None);
178 }
179 }
180 Map(child, ordered) => {
181 let fields = filter_field(child, filter)?;
182 if let Some(fields) = fields {
183 Map(fields, *ordered)
184 } else {
185 return Ok(None);
186 }
187 }
188 FixedSizeList(child, size) => {
189 let fields = filter_field(child, filter)?;
190 if let Some(fields) = fields {
191 FixedSizeList(fields, *size)
192 } else {
193 return Ok(None);
194 }
195 }
196 Struct(fields) => {
197 let filtered: Result<Vec<_>, _> =
198 fields.iter().map(|f| filter_field(f, filter)).collect();
199 let filtered: Fields = filtered?
200 .iter()
201 .filter_map(|f| f.as_ref().cloned())
202 .collect();
203
204 if filtered.is_empty() {
205 return Ok(None);
206 }
207
208 Struct(filtered)
209 }
210 Union(fields, mode) => {
211 let filtered: Result<Vec<_>, _> = fields
212 .iter()
213 .map(|(id, f)| filter_field(f, filter).map(|f| f.map(|f| (id, f))))
214 .collect();
215 let filtered: UnionFields = filtered?
216 .iter()
217 .filter_map(|f| f.as_ref().cloned())
218 .collect();
219
220 if filtered.is_empty() {
221 return Ok(None);
222 }
223
224 Union(filtered, *mode)
225 }
226 _ => {
227 let filtered = filter(f)?;
228 return Ok(filtered.then(|| f.clone()));
229 }
230 };
231 let d = match f.data_type() {
232 Dictionary(k, _) => Dictionary(k.clone(), Box::new(d)),
233 RunEndEncoded(v, f) => {
234 RunEndEncoded(v.clone(), Arc::new(f.as_ref().clone().with_data_type(d)))
235 }
236 _ => d,
237 };
238 Ok(Some(Arc::new(f.as_ref().clone().with_data_type(d))))
239 }
240
241 let mut leaf_idx = 0;
242 let mut filter = |f: &FieldRef| {
243 let t = filter(leaf_idx, f)?;
244 leaf_idx += 1;
245 Ok(t)
246 };
247
248 let filtered: Result<Vec<_>, _> = self
249 .0
250 .iter()
251 .map(|f| filter_field(f, &mut filter))
252 .collect();
253 let filtered = filtered?
254 .iter()
255 .filter_map(|f| f.as_ref().cloned())
256 .collect();
257 Ok(filtered)
258 }
259}
260
261impl Default for Fields {
262 fn default() -> Self {
263 Self::empty()
264 }
265}
266
267impl FromIterator<Field> for Fields {
268 fn from_iter<T: IntoIterator<Item = Field>>(iter: T) -> Self {
269 iter.into_iter().map(Arc::new).collect()
270 }
271}
272
273impl FromIterator<FieldRef> for Fields {
274 fn from_iter<T: IntoIterator<Item = FieldRef>>(iter: T) -> Self {
275 Self(iter.into_iter().collect())
276 }
277}
278
279impl From<Vec<Field>> for Fields {
280 fn from(value: Vec<Field>) -> Self {
281 value.into_iter().collect()
282 }
283}
284
285impl From<Vec<FieldRef>> for Fields {
286 fn from(value: Vec<FieldRef>) -> Self {
287 Self(value.into())
288 }
289}
290
291impl From<&[FieldRef]> for Fields {
292 fn from(value: &[FieldRef]) -> Self {
293 Self(value.into())
294 }
295}
296
297impl<const N: usize> From<[FieldRef; N]> for Fields {
298 fn from(value: [FieldRef; N]) -> Self {
299 Self(Arc::new(value))
300 }
301}
302
303impl Deref for Fields {
304 type Target = [FieldRef];
305
306 fn deref(&self) -> &Self::Target {
307 self.0.as_ref()
308 }
309}
310
311impl<'a> IntoIterator for &'a Fields {
312 type Item = &'a FieldRef;
313 type IntoIter = std::slice::Iter<'a, FieldRef>;
314
315 fn into_iter(self) -> Self::IntoIter {
316 self.0.iter()
317 }
318}
319
320#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
327#[cfg_attr(feature = "serde", derive(serde::Serialize))]
328#[cfg_attr(feature = "serde", serde(transparent))]
329pub struct UnionFields(Arc<[(i8, FieldRef)]>);
330
331#[cfg(feature = "serde")]
333impl<'de> serde::Deserialize<'de> for UnionFields {
334 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
335 where
336 D: serde::Deserializer<'de>,
337 {
338 let entries = Vec::<(i8, FieldRef)>::deserialize(deserializer)?;
339 let (type_ids, fields): (Vec<i8>, Vec<FieldRef>) = entries.into_iter().unzip();
340 Self::try_new(type_ids, fields).map_err(serde::de::Error::custom)
341 }
342}
343
344impl std::fmt::Debug for UnionFields {
345 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
346 self.0.as_ref().fmt(f)
347 }
348}
349
350impl std::ops::Index<usize> for UnionFields {
359 type Output = (i8, FieldRef);
360
361 fn index(&self, index: usize) -> &Self::Output {
362 &self.0[index]
363 }
364}
365
366impl UnionFields {
367 pub fn empty() -> Self {
369 Self(Arc::from([]))
370 }
371
372 pub fn try_new<F, T>(type_ids: T, fields: F) -> Result<Self, ArrowError>
410 where
411 F: IntoIterator,
412 F::Item: Into<FieldRef>,
413 T: IntoIterator<Item = i8>,
414 {
415 let mut type_ids_iter = type_ids.into_iter();
416 let mut fields_iter = fields.into_iter().map(Into::into);
417
418 let mut seen_type_ids = 0u128;
419
420 let mut out = Vec::new();
421
422 loop {
423 match (type_ids_iter.next(), fields_iter.next()) {
424 (None, None) => return Ok(Self(out.into())),
425 (Some(type_id), Some(field)) => {
426 if type_id < 0 {
428 return Err(ArrowError::InvalidArgumentError(format!(
429 "type ids must be non-negative: {type_id}"
430 )));
431 }
432
433 let mask = 1_u128 << type_id;
435 if (seen_type_ids & mask) != 0 {
436 return Err(ArrowError::InvalidArgumentError(format!(
437 "duplicate type id: {type_id}"
438 )));
439 }
440
441 seen_type_ids |= mask;
442
443 out.push((type_id, field));
444 }
445 (None, Some(_)) => {
446 return Err(ArrowError::InvalidArgumentError(
447 "fields iterator has more elements than type_ids iterator".to_string(),
448 ));
449 }
450 (Some(_), None) => {
451 return Err(ArrowError::InvalidArgumentError(
452 "type_ids iterator has more elements than fields iterator".to_string(),
453 ));
454 }
455 }
456 }
457 }
458
459 pub fn from_fields<F>(fields: F) -> Self
487 where
488 F: IntoIterator,
489 F::Item: Into<FieldRef>,
490 {
491 fields
492 .into_iter()
493 .enumerate()
494 .map(|(i, field)| {
495 let id = i8::try_from(i).expect("UnionFields cannot contain more than 128 fields");
496
497 (id, field.into())
498 })
499 .collect()
500 }
501
502 pub fn try_from_fields<F>(fields: F) -> Result<Self, ArrowError>
537 where
538 F: IntoIterator,
539 F::Item: Into<FieldRef>,
540 {
541 let mut out = Vec::with_capacity(i8::MAX as usize + 1);
542
543 for (i, field) in fields.into_iter().enumerate() {
544 let id = i8::try_from(i).map_err(|_| {
545 ArrowError::InvalidArgumentError(
546 "UnionFields cannot contain more than 128 fields".into(),
547 )
548 })?;
549
550 out.push((id, field.into()));
551 }
552
553 Ok(Self(out.into()))
554 }
555
556 #[deprecated(since = "57.0.0", note = "Use `try_new` instead")]
583 pub fn new<F, T>(type_ids: T, fields: F) -> Self
584 where
585 F: IntoIterator,
586 F::Item: Into<FieldRef>,
587 T: IntoIterator<Item = i8>,
588 {
589 let fields = fields.into_iter().map(Into::into);
590 let mut set = 0_u128;
591 type_ids
592 .into_iter()
593 .inspect(|&idx| {
594 let mask = 1_u128 << idx;
595 if (set & mask) != 0 {
596 panic!("duplicate type id: {idx}");
597 } else {
598 set |= mask;
599 }
600 })
601 .zip(fields)
602 .collect()
603 }
604
605 pub fn size(&self) -> usize {
607 self.iter()
608 .map(|(_, field)| field.size() + std::mem::size_of::<(i8, FieldRef)>())
609 .sum()
610 }
611
612 pub fn len(&self) -> usize {
614 self.0.len()
615 }
616
617 pub fn is_empty(&self) -> bool {
619 self.0.is_empty()
620 }
621
622 pub fn iter(&self) -> impl Iterator<Item = (i8, &FieldRef)> + '_ {
624 self.0.iter().map(|(id, f)| (*id, f))
625 }
626
627 pub fn get(&self, index: usize) -> Option<&(i8, FieldRef)> {
649 self.0.get(index)
650 }
651
652 pub fn find_by_type_id(&self, type_id: i8) -> Option<(i8, &FieldRef)> {
655 self.iter().find(|&(i, _)| i == type_id)
656 }
657
658 pub fn find_by_field(&self, field: &Field) -> Option<(i8, &FieldRef)> {
661 self.iter().find(|&(_, f)| f.as_ref() == field)
662 }
663
664 pub(crate) fn try_merge(&mut self, other: &Self) -> Result<(), ArrowError> {
668 let mut output: Vec<_> = self.iter().map(|(id, f)| (id, f.clone())).collect();
670 for (field_type_id, from_field) in other.iter() {
671 let mut is_new_field = true;
672 for (self_type_id, self_field) in output.iter_mut() {
673 if from_field == self_field {
674 if *self_type_id != field_type_id {
677 return Err(ArrowError::SchemaError(format!(
678 "Fail to merge schema field '{}' because the self_type_id = {} does not equal field_type_id = {}",
679 self_field.name(),
680 self_type_id,
681 field_type_id
682 )));
683 }
684
685 is_new_field = false;
686 break;
687 }
688 }
689
690 if is_new_field {
691 output.push((field_type_id, from_field.clone()))
692 }
693 }
694 let (type_ids, fields): (Vec<i8>, Vec<FieldRef>) = output.into_iter().unzip();
697 *self = Self::try_new(type_ids, fields)?;
698 Ok(())
699 }
700}
701
702impl FromIterator<(i8, FieldRef)> for UnionFields {
703 fn from_iter<T: IntoIterator<Item = (i8, FieldRef)>>(iter: T) -> Self {
711 let iter = iter.into_iter();
712 let (type_ids, fields): (Vec<i8>, Vec<FieldRef>) = iter.unzip();
713 Self::try_new(type_ids, fields).expect("invalid arguments passed")
714 }
715}
716
717#[cfg(test)]
718mod tests {
719 use super::*;
720 use crate::UnionMode;
721
722 #[test]
723 fn test_filter() {
724 let floats = Fields::from(vec![
725 Field::new("a", DataType::Float32, false),
726 Field::new("b", DataType::Float32, false),
727 ]);
728 let fields = Fields::from(vec![
729 Field::new("a", DataType::Int32, true),
730 Field::new("floats", DataType::Struct(floats.clone()), true),
731 Field::new("b", DataType::Int16, true),
732 Field::new(
733 "c",
734 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
735 false,
736 ),
737 Field::new(
738 "d",
739 DataType::Dictionary(
740 Box::new(DataType::Int32),
741 Box::new(DataType::Struct(floats.clone())),
742 ),
743 false,
744 ),
745 Field::new_list(
746 "e",
747 Field::new("floats", DataType::Struct(floats.clone()), true),
748 true,
749 ),
750 Field::new_fixed_size_list(
751 "f",
752 Field::new_list_field(DataType::Int32, false),
753 3,
754 false,
755 ),
756 Field::new_map(
757 "g",
758 "entries",
759 Field::new("keys", DataType::LargeUtf8, false),
760 Field::new("values", DataType::Int32, true),
761 false,
762 false,
763 ),
764 Field::new(
765 "h",
766 DataType::Union(
767 UnionFields::try_new(
768 vec![1, 3],
769 vec![
770 Field::new("field1", DataType::UInt8, false),
771 Field::new("field3", DataType::Utf8, false),
772 ],
773 )
774 .unwrap(),
775 UnionMode::Dense,
776 ),
777 true,
778 ),
779 Field::new(
780 "i",
781 DataType::RunEndEncoded(
782 Arc::new(Field::new("run_ends", DataType::Int32, false)),
783 Arc::new(Field::new("values", DataType::Struct(floats.clone()), true)),
784 ),
785 false,
786 ),
787 ]);
788
789 let floats_a = DataType::Struct(vec![floats[0].clone()].into());
790
791 let r = fields.filter_leaves(|idx, _| idx == 0 || idx == 1);
792 assert_eq!(r.len(), 2);
793 assert_eq!(r[0], fields[0]);
794 assert_eq!(r[1].data_type(), &floats_a);
795
796 let r = fields.filter_leaves(|_, f| f.name() == "a");
797 assert_eq!(r.len(), 5);
798 assert_eq!(r[0], fields[0]);
799 assert_eq!(r[1].data_type(), &floats_a);
800 assert_eq!(
801 r[2].data_type(),
802 &DataType::Dictionary(Box::new(DataType::Int32), Box::new(floats_a.clone()))
803 );
804 assert_eq!(
805 r[3].as_ref(),
806 &Field::new_list("e", Field::new("floats", floats_a.clone(), true), true)
807 );
808 assert_eq!(
809 r[4].as_ref(),
810 &Field::new(
811 "i",
812 DataType::RunEndEncoded(
813 Arc::new(Field::new("run_ends", DataType::Int32, false)),
814 Arc::new(Field::new("values", floats_a.clone(), true)),
815 ),
816 false,
817 )
818 );
819
820 let r = fields.filter_leaves(|_, f| f.name() == "floats");
821 assert_eq!(r.len(), 0);
822
823 let r = fields.filter_leaves(|idx, _| idx == 9);
824 assert_eq!(r.len(), 1);
825 assert_eq!(r[0], fields[6]);
826
827 let r = fields.filter_leaves(|idx, _| idx == 10 || idx == 11);
828 assert_eq!(r.len(), 1);
829 assert_eq!(r[0], fields[7]);
830
831 let union = DataType::Union(
832 UnionFields::try_new(vec![1], vec![Field::new("field1", DataType::UInt8, false)])
833 .unwrap(),
834 UnionMode::Dense,
835 );
836
837 let r = fields.filter_leaves(|idx, _| idx == 12);
838 assert_eq!(r.len(), 1);
839 assert_eq!(r[0].data_type(), &union);
840
841 let r = fields.filter_leaves(|idx, _| idx == 14 || idx == 15);
842 assert_eq!(r.len(), 1);
843 assert_eq!(r[0], fields[9]);
844
845 let r = fields.try_filter_leaves(|_, _| Err(ArrowError::SchemaError("error".to_string())));
847 assert!(r.is_err());
848 }
849
850 #[test]
851 fn test_union_fields_try_new_valid() {
852 let res = UnionFields::try_new(
853 vec![1, 6, 7],
854 vec![
855 Field::new("f1", DataType::UInt8, false),
856 Field::new("f6", DataType::Utf8, false),
857 Field::new("f7", DataType::Int32, true),
858 ],
859 );
860 assert!(res.is_ok());
861 let union_fields = res.unwrap();
862 assert_eq!(union_fields.len(), 3);
863 assert_eq!(
864 union_fields.iter().map(|(id, _)| id).collect::<Vec<_>>(),
865 vec![1, 6, 7]
866 );
867 }
868
869 #[test]
870 fn test_union_fields_try_new_empty() {
871 let res = UnionFields::try_new(Vec::<i8>::new(), Vec::<Field>::new());
872 assert!(res.is_ok());
873 assert!(res.unwrap().is_empty());
874 }
875
876 #[test]
877 fn test_union_fields_try_new_duplicate_type_id() {
878 let res = UnionFields::try_new(
879 vec![1, 1],
880 vec![
881 Field::new("f1", DataType::UInt8, false),
882 Field::new("f2", DataType::Utf8, false),
883 ],
884 );
885 assert!(res.is_err());
886 assert!(
887 res.unwrap_err()
888 .to_string()
889 .contains("duplicate type id: 1")
890 );
891 }
892
893 #[test]
894 fn test_union_fields_try_new_duplicate_field() {
895 let field = Field::new("field", DataType::UInt8, false);
896 let res = UnionFields::try_new(vec![1, 2], vec![field.clone(), field]);
897 assert!(res.is_ok());
898 }
899
900 #[test]
901 fn test_union_fields_try_new_more_type_ids() {
902 let res = UnionFields::try_new(
903 vec![1, 2, 3],
904 vec![
905 Field::new("f1", DataType::UInt8, false),
906 Field::new("f2", DataType::Utf8, false),
907 ],
908 );
909 assert!(res.is_err());
910 assert!(
911 res.unwrap_err()
912 .to_string()
913 .contains("type_ids iterator has more elements")
914 );
915 }
916
917 #[test]
918 fn test_union_fields_try_new_more_fields() {
919 let res = UnionFields::try_new(
920 vec![1, 2],
921 vec![
922 Field::new("f1", DataType::UInt8, false),
923 Field::new("f2", DataType::Utf8, false),
924 Field::new("f3", DataType::Int32, true),
925 ],
926 );
927 assert!(res.is_err());
928 assert!(
929 res.unwrap_err()
930 .to_string()
931 .contains("fields iterator has more elements")
932 );
933 }
934
935 #[test]
936 fn test_union_fields_try_new_negative_type_ids() {
937 let res = UnionFields::try_new(
938 vec![-128, -1, 0, 127],
939 vec![
940 Field::new("field_min", DataType::UInt8, false),
941 Field::new("field_neg", DataType::Utf8, false),
942 Field::new("field_zero", DataType::Int32, true),
943 Field::new("field_max", DataType::Boolean, false),
944 ],
945 );
946 assert!(res.is_err());
947 assert!(
948 res.unwrap_err()
949 .to_string()
950 .contains("type ids must be non-negative")
951 )
952 }
953
954 #[test]
955 fn test_union_fields_try_new_complex_types() {
956 let res = UnionFields::try_new(
957 vec![0, 1, 2],
958 vec![
959 Field::new(
960 "struct_field",
961 DataType::Struct(Fields::from(vec![
962 Field::new("a", DataType::Int32, false),
963 Field::new("b", DataType::Utf8, true),
964 ])),
965 false,
966 ),
967 Field::new_list(
968 "list_field",
969 Field::new("item", DataType::Float64, true),
970 true,
971 ),
972 Field::new(
973 "dict_field",
974 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
975 false,
976 ),
977 ],
978 );
979 assert!(res.is_ok());
980 assert_eq!(res.unwrap().len(), 3);
981 }
982
983 #[test]
984 fn test_union_fields_try_new_single_field() {
985 let res = UnionFields::try_new(
986 vec![42],
987 vec![Field::new("only_field", DataType::Int64, false)],
988 );
989 assert!(res.is_ok());
990 let union_fields = res.unwrap();
991 assert_eq!(union_fields.len(), 1);
992 assert_eq!(union_fields.iter().next().unwrap().0, 42);
993 }
994
995 #[test]
996 fn test_union_fields_try_from_fields_empty() {
997 let res = UnionFields::try_from_fields(Vec::<Field>::new());
998 assert!(res.is_ok());
999 assert!(res.unwrap().is_empty());
1000 }
1001
1002 #[test]
1003 fn test_union_fields_try_from_fields_single() {
1004 let res = UnionFields::try_from_fields(vec![Field::new("only", DataType::Int64, false)]);
1005 assert!(res.is_ok());
1006 let union_fields = res.unwrap();
1007 assert_eq!(union_fields.len(), 1);
1008 assert_eq!(union_fields.iter().next().unwrap().0, 0);
1009 }
1010
1011 #[test]
1012 fn test_union_fields_try_from_fields_too_many() {
1013 let many_fields: Vec<_> = (0..200)
1014 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
1015 .collect();
1016 let res = UnionFields::try_from_fields(many_fields);
1017 assert!(res.is_err());
1018 assert!(
1019 res.unwrap_err()
1020 .to_string()
1021 .contains("UnionFields cannot contain more than 128 fields")
1022 );
1023 }
1024
1025 #[test]
1026 fn test_union_fields_try_from_fields_max_valid() {
1027 let fields: Vec<_> = (0..=i8::MAX)
1028 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
1029 .collect();
1030 let res = UnionFields::try_from_fields(fields);
1031 assert!(res.is_ok());
1032 let union_fields = res.unwrap();
1033 assert_eq!(union_fields.len(), 128);
1034 assert_eq!(union_fields.iter().map(|(id, _)| id).min().unwrap(), 0);
1035 assert_eq!(union_fields.iter().map(|(id, _)| id).max().unwrap(), 127);
1036 }
1037
1038 #[test]
1039 fn test_union_fields_try_from_fields_over_max() {
1040 let fields: Vec<_> = (0..129)
1042 .map(|i| Field::new(format!("field{}", i), DataType::Int32, false))
1043 .collect();
1044 let res = UnionFields::try_from_fields(fields);
1045 assert!(res.is_err());
1046 }
1047
1048 #[test]
1049 fn test_union_fields_try_from_fields_complex_types() {
1050 let res = UnionFields::try_from_fields(vec![
1051 Field::new(
1052 "struct_field",
1053 DataType::Struct(Fields::from(vec![
1054 Field::new("a", DataType::Int32, false),
1055 Field::new("b", DataType::Utf8, true),
1056 ])),
1057 false,
1058 ),
1059 Field::new_list(
1060 "list_field",
1061 Field::new("item", DataType::Float64, true),
1062 true,
1063 ),
1064 Field::new(
1065 "dict_field",
1066 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
1067 false,
1068 ),
1069 ]);
1070 assert!(res.is_ok());
1071 assert_eq!(res.unwrap().len(), 3);
1072 }
1073
1074 #[test]
1075 #[should_panic(
1076 expected = "invalid arguments passed: InvalidArgumentError(\"type ids must be non-negative: -1\")"
1077 )]
1078 fn test_union_fields_from_iter_should_validate() {
1079 let fields: Vec<(i8, FieldRef)> = vec![
1080 (0, Arc::new(Field::new("a", DataType::Int32, true))),
1081 (-1, Arc::new(Field::new("a", DataType::Int32, true))),
1082 ];
1083 UnionFields::from_iter(fields);
1084 }
1085
1086 #[cfg(feature = "serde")]
1087 #[test]
1088 fn test_union_fields_serde_round_trip() {
1089 let fields = UnionFields::try_new(
1090 vec![1, 3],
1091 vec![
1092 Field::new("a", DataType::Int32, true),
1093 Field::new("b", DataType::Utf8, true),
1094 ],
1095 )
1096 .unwrap();
1097 let serialized = postcard::to_stdvec(&fields).unwrap();
1098 let deserialized: UnionFields = postcard::from_bytes(&serialized).unwrap();
1099 assert_eq!(fields, deserialized);
1100 }
1101
1102 #[cfg(feature = "serde")]
1103 #[test]
1104 fn test_union_fields_deserialize_should_validate() {
1105 let field = Arc::new(Field::new("a", DataType::Int32, true));
1106
1107 let duplicate: Vec<(i8, FieldRef)> = vec![(1, Arc::clone(&field)), (1, Arc::clone(&field))];
1108 let serialized = serde_json::to_string(&duplicate).unwrap();
1109 let err = serde_json::from_str::<UnionFields>(&serialized).unwrap_err();
1110 assert!(err.to_string().contains("duplicate type id: 1"), "{err}");
1111
1112 let negative: Vec<(i8, FieldRef)> = vec![(0, Arc::clone(&field)), (-1, field)];
1113 let serialized = serde_json::to_string(&negative).unwrap();
1114 let err = serde_json::from_str::<UnionFields>(&serialized).unwrap_err();
1115 assert!(
1116 err.to_string()
1117 .contains("type ids must be non-negative: -1"),
1118 "{err}"
1119 );
1120 }
1121}