1use crate::array::print_long_array;
19use crate::iterator::FixedSizeBinaryIter;
20use crate::{Array, ArrayAccessor, ArrayRef, FixedSizeListArray, Scalar};
21use arrow_buffer::buffer::NullBuffer;
22use arrow_buffer::{bit_util, ArrowNativeType, BooleanBuffer, Buffer, MutableBuffer};
23use arrow_data::{ArrayData, ArrayDataBuilder};
24use arrow_schema::{ArrowError, DataType};
25use std::any::Any;
26use std::sync::Arc;
27
28#[derive(Clone)]
53pub struct FixedSizeBinaryArray {
54 data_type: DataType, value_data: Buffer,
56 nulls: Option<NullBuffer>,
57 len: usize,
58 value_length: i32,
59}
60
61impl FixedSizeBinaryArray {
62 pub fn new(size: i32, values: Buffer, nulls: Option<NullBuffer>) -> Self {
68 Self::try_new(size, values, nulls).unwrap()
69 }
70
71 pub fn new_scalar(value: impl AsRef<[u8]>) -> Scalar<Self> {
73 let v = value.as_ref();
74 Scalar::new(Self::new(v.len() as _, Buffer::from(v), None))
75 }
76
77 pub fn try_new(
84 size: i32,
85 values: Buffer,
86 nulls: Option<NullBuffer>,
87 ) -> Result<Self, ArrowError> {
88 let data_type = DataType::FixedSizeBinary(size);
89 let s = size.to_usize().ok_or_else(|| {
90 ArrowError::InvalidArgumentError(format!("Size cannot be negative, got {}", size))
91 })?;
92
93 let len = values.len() / s;
94 if let Some(n) = nulls.as_ref() {
95 if n.len() != len {
96 return Err(ArrowError::InvalidArgumentError(format!(
97 "Incorrect length of null buffer for FixedSizeBinaryArray, expected {} got {}",
98 len,
99 n.len(),
100 )));
101 }
102 }
103
104 Ok(Self {
105 data_type,
106 value_data: values,
107 value_length: size,
108 nulls,
109 len,
110 })
111 }
112
113 pub fn new_null(size: i32, len: usize) -> Self {
122 let capacity = size.to_usize().unwrap().checked_mul(len).unwrap();
123 Self {
124 data_type: DataType::FixedSizeBinary(size),
125 value_data: MutableBuffer::new(capacity).into(),
126 nulls: Some(NullBuffer::new_null(len)),
127 value_length: size,
128 len,
129 }
130 }
131
132 pub fn into_parts(self) -> (i32, Buffer, Option<NullBuffer>) {
134 (self.value_length, self.value_data, self.nulls)
135 }
136
137 pub fn value(&self, i: usize) -> &[u8] {
141 assert!(
142 i < self.len(),
143 "Trying to access an element at index {} from a FixedSizeBinaryArray of length {}",
144 i,
145 self.len()
146 );
147 let offset = i + self.offset();
148 unsafe {
149 let pos = self.value_offset_at(offset);
150 std::slice::from_raw_parts(
151 self.value_data.as_ptr().offset(pos as isize),
152 (self.value_offset_at(offset + 1) - pos) as usize,
153 )
154 }
155 }
156
157 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
161 let offset = i + self.offset();
162 let pos = self.value_offset_at(offset);
163 std::slice::from_raw_parts(
164 self.value_data.as_ptr().offset(pos as isize),
165 (self.value_offset_at(offset + 1) - pos) as usize,
166 )
167 }
168
169 #[inline]
173 pub fn value_offset(&self, i: usize) -> i32 {
174 self.value_offset_at(self.offset() + i)
175 }
176
177 #[inline]
181 pub fn value_length(&self) -> i32 {
182 self.value_length
183 }
184
185 #[inline]
190 pub fn values(&self) -> &Buffer {
191 &self.value_data
192 }
193
194 pub fn value_data(&self) -> &[u8] {
196 self.value_data.as_slice()
197 }
198
199 pub fn slice(&self, offset: usize, len: usize) -> Self {
201 assert!(
202 offset.saturating_add(len) <= self.len,
203 "the length + offset of the sliced FixedSizeBinaryArray cannot exceed the existing length"
204 );
205
206 let size = self.value_length as usize;
207
208 Self {
209 data_type: self.data_type.clone(),
210 nulls: self.nulls.as_ref().map(|n| n.slice(offset, len)),
211 value_length: self.value_length,
212 value_data: self.value_data.slice_with_length(offset * size, len * size),
213 len,
214 }
215 }
216
217 #[deprecated(
240 note = "This function will fail if the iterator produces only None values; prefer `try_from_sparse_iter_with_size`"
241 )]
242 pub fn try_from_sparse_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
243 where
244 T: Iterator<Item = Option<U>>,
245 U: AsRef<[u8]>,
246 {
247 let mut len = 0;
248 let mut size = None;
249 let mut byte = 0;
250
251 let iter_size_hint = iter.size_hint().0;
252 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
253 let mut buffer = MutableBuffer::new(0);
254
255 let mut prepend = 0;
256 iter.try_for_each(|item| -> Result<(), ArrowError> {
257 if byte == 0 {
259 null_buf.push(0u8);
260 byte = 8;
261 }
262 byte -= 1;
263
264 if let Some(slice) = item {
265 let slice = slice.as_ref();
266 if let Some(size) = size {
267 if size != slice.len() {
268 return Err(ArrowError::InvalidArgumentError(format!(
269 "Nested array size mismatch: one is {}, and the other is {}",
270 size,
271 slice.len()
272 )));
273 }
274 } else {
275 let len = slice.len();
276 size = Some(len);
277 buffer.reserve(iter_size_hint * len);
281 buffer.extend_zeros(slice.len() * prepend);
282 }
283 bit_util::set_bit(null_buf.as_slice_mut(), len);
284 buffer.extend_from_slice(slice);
285 } else if let Some(size) = size {
286 buffer.extend_zeros(size);
287 } else {
288 prepend += 1;
289 }
290
291 len += 1;
292
293 Ok(())
294 })?;
295
296 if len == 0 {
297 return Err(ArrowError::InvalidArgumentError(
298 "Input iterable argument has no data".to_owned(),
299 ));
300 }
301
302 let null_buf = BooleanBuffer::new(null_buf.into(), 0, len);
303 let nulls = Some(NullBuffer::new(null_buf)).filter(|n| n.null_count() > 0);
304
305 let size = size.unwrap_or(0) as i32;
306 Ok(Self {
307 data_type: DataType::FixedSizeBinary(size),
308 value_data: buffer.into(),
309 nulls,
310 value_length: size,
311 len,
312 })
313 }
314
315 pub fn try_from_sparse_iter_with_size<T, U>(mut iter: T, size: i32) -> Result<Self, ArrowError>
340 where
341 T: Iterator<Item = Option<U>>,
342 U: AsRef<[u8]>,
343 {
344 let mut len = 0;
345 let mut byte = 0;
346
347 let iter_size_hint = iter.size_hint().0;
348 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
349 let mut buffer = MutableBuffer::new(iter_size_hint * (size as usize));
350
351 iter.try_for_each(|item| -> Result<(), ArrowError> {
352 if byte == 0 {
354 null_buf.push(0u8);
355 byte = 8;
356 }
357 byte -= 1;
358
359 if let Some(slice) = item {
360 let slice = slice.as_ref();
361 if size as usize != slice.len() {
362 return Err(ArrowError::InvalidArgumentError(format!(
363 "Nested array size mismatch: one is {}, and the other is {}",
364 size,
365 slice.len()
366 )));
367 }
368
369 bit_util::set_bit(null_buf.as_slice_mut(), len);
370 buffer.extend_from_slice(slice);
371 } else {
372 buffer.extend_zeros(size as usize);
373 }
374
375 len += 1;
376
377 Ok(())
378 })?;
379
380 let null_buf = BooleanBuffer::new(null_buf.into(), 0, len);
381 let nulls = Some(NullBuffer::new(null_buf)).filter(|n| n.null_count() > 0);
382
383 Ok(Self {
384 data_type: DataType::FixedSizeBinary(size),
385 value_data: buffer.into(),
386 nulls,
387 len,
388 value_length: size,
389 })
390 }
391
392 pub fn try_from_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
410 where
411 T: Iterator<Item = U>,
412 U: AsRef<[u8]>,
413 {
414 let mut len = 0;
415 let mut size = None;
416 let iter_size_hint = iter.size_hint().0;
417 let mut buffer = MutableBuffer::new(0);
418
419 iter.try_for_each(|item| -> Result<(), ArrowError> {
420 let slice = item.as_ref();
421 if let Some(size) = size {
422 if size != slice.len() {
423 return Err(ArrowError::InvalidArgumentError(format!(
424 "Nested array size mismatch: one is {}, and the other is {}",
425 size,
426 slice.len()
427 )));
428 }
429 } else {
430 let len = slice.len();
431 size = Some(len);
432 buffer.reserve(iter_size_hint * len);
433 }
434
435 buffer.extend_from_slice(slice);
436
437 len += 1;
438
439 Ok(())
440 })?;
441
442 if len == 0 {
443 return Err(ArrowError::InvalidArgumentError(
444 "Input iterable argument has no data".to_owned(),
445 ));
446 }
447
448 let size = size.unwrap_or(0).try_into().unwrap();
449 Ok(Self {
450 data_type: DataType::FixedSizeBinary(size),
451 value_data: buffer.into(),
452 nulls: None,
453 value_length: size,
454 len,
455 })
456 }
457
458 #[inline]
459 fn value_offset_at(&self, i: usize) -> i32 {
460 self.value_length * i as i32
461 }
462
463 pub fn iter(&self) -> FixedSizeBinaryIter<'_> {
465 FixedSizeBinaryIter::new(self)
466 }
467}
468
469impl From<ArrayData> for FixedSizeBinaryArray {
470 fn from(data: ArrayData) -> Self {
471 assert_eq!(
472 data.buffers().len(),
473 1,
474 "FixedSizeBinaryArray data should contain 1 buffer only (values)"
475 );
476 let value_length = match data.data_type() {
477 DataType::FixedSizeBinary(len) => *len,
478 _ => panic!("Expected data type to be FixedSizeBinary"),
479 };
480
481 let size = value_length as usize;
482 let value_data =
483 data.buffers()[0].slice_with_length(data.offset() * size, data.len() * size);
484
485 Self {
486 data_type: data.data_type().clone(),
487 nulls: data.nulls().cloned(),
488 len: data.len(),
489 value_data,
490 value_length,
491 }
492 }
493}
494
495impl From<FixedSizeBinaryArray> for ArrayData {
496 fn from(array: FixedSizeBinaryArray) -> Self {
497 let builder = ArrayDataBuilder::new(array.data_type)
498 .len(array.len)
499 .buffers(vec![array.value_data])
500 .nulls(array.nulls);
501
502 unsafe { builder.build_unchecked() }
503 }
504}
505
506impl From<FixedSizeListArray> for FixedSizeBinaryArray {
508 fn from(v: FixedSizeListArray) -> Self {
509 let value_len = v.value_length();
510 let v = v.into_data();
511 assert_eq!(
512 v.child_data().len(),
513 1,
514 "FixedSizeBinaryArray can only be created from list array of u8 values \
515 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
516 );
517 let child_data = &v.child_data()[0];
518
519 assert_eq!(
520 child_data.child_data().len(),
521 0,
522 "FixedSizeBinaryArray can only be created from list array of u8 values \
523 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
524 );
525 assert_eq!(
526 child_data.data_type(),
527 &DataType::UInt8,
528 "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
529 );
530 assert_eq!(
531 child_data.null_count(),
532 0,
533 "The child array cannot contain null values."
534 );
535
536 let builder = ArrayData::builder(DataType::FixedSizeBinary(value_len))
537 .len(v.len())
538 .offset(v.offset())
539 .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
540 .nulls(v.nulls().cloned());
541
542 let data = unsafe { builder.build_unchecked() };
543 Self::from(data)
544 }
545}
546
547impl From<Vec<Option<&[u8]>>> for FixedSizeBinaryArray {
548 fn from(v: Vec<Option<&[u8]>>) -> Self {
549 #[allow(deprecated)]
550 Self::try_from_sparse_iter(v.into_iter()).unwrap()
551 }
552}
553
554impl From<Vec<&[u8]>> for FixedSizeBinaryArray {
555 fn from(v: Vec<&[u8]>) -> Self {
556 Self::try_from_iter(v.into_iter()).unwrap()
557 }
558}
559
560impl<const N: usize> From<Vec<&[u8; N]>> for FixedSizeBinaryArray {
561 fn from(v: Vec<&[u8; N]>) -> Self {
562 Self::try_from_iter(v.into_iter()).unwrap()
563 }
564}
565
566impl std::fmt::Debug for FixedSizeBinaryArray {
567 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
568 write!(f, "FixedSizeBinaryArray<{}>\n[\n", self.value_length())?;
569 print_long_array(self, f, |array, index, f| {
570 std::fmt::Debug::fmt(&array.value(index), f)
571 })?;
572 write!(f, "]")
573 }
574}
575
576impl Array for FixedSizeBinaryArray {
577 fn as_any(&self) -> &dyn Any {
578 self
579 }
580
581 fn to_data(&self) -> ArrayData {
582 self.clone().into()
583 }
584
585 fn into_data(self) -> ArrayData {
586 self.into()
587 }
588
589 fn data_type(&self) -> &DataType {
590 &self.data_type
591 }
592
593 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
594 Arc::new(self.slice(offset, length))
595 }
596
597 fn len(&self) -> usize {
598 self.len
599 }
600
601 fn is_empty(&self) -> bool {
602 self.len == 0
603 }
604
605 fn shrink_to_fit(&mut self) {
606 self.value_data.shrink_to_fit();
607 if let Some(nulls) = &mut self.nulls {
608 nulls.shrink_to_fit();
609 }
610 }
611
612 fn offset(&self) -> usize {
613 0
614 }
615
616 fn nulls(&self) -> Option<&NullBuffer> {
617 self.nulls.as_ref()
618 }
619
620 fn logical_null_count(&self) -> usize {
621 self.null_count()
623 }
624
625 fn get_buffer_memory_size(&self) -> usize {
626 let mut sum = self.value_data.capacity();
627 if let Some(n) = &self.nulls {
628 sum += n.buffer().capacity();
629 }
630 sum
631 }
632
633 fn get_array_memory_size(&self) -> usize {
634 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
635 }
636}
637
638impl<'a> ArrayAccessor for &'a FixedSizeBinaryArray {
639 type Item = &'a [u8];
640
641 fn value(&self, index: usize) -> Self::Item {
642 FixedSizeBinaryArray::value(self, index)
643 }
644
645 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
646 FixedSizeBinaryArray::value_unchecked(self, index)
647 }
648}
649
650impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
651 type Item = Option<&'a [u8]>;
652 type IntoIter = FixedSizeBinaryIter<'a>;
653
654 fn into_iter(self) -> Self::IntoIter {
655 FixedSizeBinaryIter::<'a>::new(self)
656 }
657}
658
659#[cfg(test)]
660mod tests {
661 use crate::RecordBatch;
662 use arrow_schema::{Field, Schema};
663
664 use super::*;
665
666 #[test]
667 fn test_fixed_size_binary_array() {
668 let values: [u8; 15] = *b"hellotherearrow";
669
670 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
671 .len(3)
672 .add_buffer(Buffer::from(&values[..]))
673 .build()
674 .unwrap();
675 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
676 assert_eq!(3, fixed_size_binary_array.len());
677 assert_eq!(0, fixed_size_binary_array.null_count());
678 assert_eq!(
679 [b'h', b'e', b'l', b'l', b'o'],
680 fixed_size_binary_array.value(0)
681 );
682 assert_eq!(
683 [b't', b'h', b'e', b'r', b'e'],
684 fixed_size_binary_array.value(1)
685 );
686 assert_eq!(
687 [b'a', b'r', b'r', b'o', b'w'],
688 fixed_size_binary_array.value(2)
689 );
690 assert_eq!(5, fixed_size_binary_array.value_length());
691 assert_eq!(10, fixed_size_binary_array.value_offset(2));
692 for i in 0..3 {
693 assert!(fixed_size_binary_array.is_valid(i));
694 assert!(!fixed_size_binary_array.is_null(i));
695 }
696
697 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
699 .len(2)
700 .offset(1)
701 .add_buffer(Buffer::from(&values[..]))
702 .build()
703 .unwrap();
704 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
705 assert_eq!(
706 [b't', b'h', b'e', b'r', b'e'],
707 fixed_size_binary_array.value(0)
708 );
709 assert_eq!(
710 [b'a', b'r', b'r', b'o', b'w'],
711 fixed_size_binary_array.value(1)
712 );
713 assert_eq!(2, fixed_size_binary_array.len());
714 assert_eq!(0, fixed_size_binary_array.value_offset(0));
715 assert_eq!(5, fixed_size_binary_array.value_length());
716 assert_eq!(5, fixed_size_binary_array.value_offset(1));
717 }
718
719 #[test]
720 fn test_fixed_size_binary_array_from_fixed_size_list_array() {
721 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
722 let values_data = ArrayData::builder(DataType::UInt8)
723 .len(12)
724 .offset(2)
725 .add_buffer(Buffer::from_slice_ref(values))
726 .build()
727 .unwrap();
728 let array_data = unsafe {
730 ArrayData::builder(DataType::FixedSizeList(
731 Arc::new(Field::new("item", DataType::UInt8, false)),
732 4,
733 ))
734 .len(2)
735 .offset(1)
736 .add_child_data(values_data)
737 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101])))
738 .build_unchecked()
739 };
740 let list_array = FixedSizeListArray::from(array_data);
741 let binary_array = FixedSizeBinaryArray::from(list_array);
742
743 assert_eq!(2, binary_array.len());
744 assert_eq!(1, binary_array.null_count());
745 assert!(binary_array.is_null(0));
746 assert!(binary_array.is_valid(1));
747 assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
748 }
749
750 #[test]
751 #[should_panic(
752 expected = "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays"
753 )]
754 #[cfg(not(feature = "force_validate"))]
757 fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
758 let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
759 let values_data = ArrayData::builder(DataType::UInt32)
760 .len(12)
761 .add_buffer(Buffer::from_slice_ref(values))
762 .build()
763 .unwrap();
764
765 let array_data = unsafe {
766 ArrayData::builder(DataType::FixedSizeList(
767 Arc::new(Field::new("item", DataType::Binary, false)),
768 4,
769 ))
770 .len(3)
771 .add_child_data(values_data)
772 .build_unchecked()
773 };
774 let list_array = FixedSizeListArray::from(array_data);
775 drop(FixedSizeBinaryArray::from(list_array));
776 }
777
778 #[test]
779 #[should_panic(expected = "The child array cannot contain null values.")]
780 fn test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed() {
781 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
782 let values_data = ArrayData::builder(DataType::UInt8)
783 .len(12)
784 .add_buffer(Buffer::from_slice_ref(values))
785 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101010101010])))
786 .build()
787 .unwrap();
788
789 let array_data = unsafe {
790 ArrayData::builder(DataType::FixedSizeList(
791 Arc::new(Field::new("item", DataType::UInt8, false)),
792 4,
793 ))
794 .len(3)
795 .add_child_data(values_data)
796 .build_unchecked()
797 };
798 let list_array = FixedSizeListArray::from(array_data);
799 drop(FixedSizeBinaryArray::from(list_array));
800 }
801
802 #[test]
803 fn test_fixed_size_binary_array_fmt_debug() {
804 let values: [u8; 15] = *b"hellotherearrow";
805
806 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
807 .len(3)
808 .add_buffer(Buffer::from(&values[..]))
809 .build()
810 .unwrap();
811 let arr = FixedSizeBinaryArray::from(array_data);
812 assert_eq!(
813 "FixedSizeBinaryArray<5>\n[\n [104, 101, 108, 108, 111],\n [116, 104, 101, 114, 101],\n [97, 114, 114, 111, 119],\n]",
814 format!("{arr:?}")
815 );
816 }
817
818 #[test]
819 fn test_fixed_size_binary_array_from_iter() {
820 let input_arg = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
821 let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
822
823 assert_eq!(2, arr.value_length());
824 assert_eq!(3, arr.len())
825 }
826
827 #[test]
828 fn test_all_none_fixed_size_binary_array_from_sparse_iter() {
829 let none_option: Option<[u8; 32]> = None;
830 let input_arg = vec![none_option, none_option, none_option];
831 #[allow(deprecated)]
832 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.into_iter()).unwrap();
833 assert_eq!(0, arr.value_length());
834 assert_eq!(3, arr.len())
835 }
836
837 #[test]
838 fn test_fixed_size_binary_array_from_sparse_iter() {
839 let input_arg = vec![
840 None,
841 Some(vec![7, 8]),
842 Some(vec![9, 10]),
843 None,
844 Some(vec![13, 14]),
845 ];
846 #[allow(deprecated)]
847 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.iter().cloned()).unwrap();
848 assert_eq!(2, arr.value_length());
849 assert_eq!(5, arr.len());
850
851 let arr =
852 FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 2).unwrap();
853 assert_eq!(2, arr.value_length());
854 assert_eq!(5, arr.len());
855 }
856
857 #[test]
858 fn test_fixed_size_binary_array_from_sparse_iter_with_size_all_none() {
859 let input_arg = vec![None, None, None, None, None] as Vec<Option<Vec<u8>>>;
860
861 let arr = FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 16)
862 .unwrap();
863 assert_eq!(16, arr.value_length());
864 assert_eq!(5, arr.len())
865 }
866
867 #[test]
868 fn test_fixed_size_binary_array_from_vec() {
869 let values = vec!["one".as_bytes(), b"two", b"six", b"ten"];
870 let array = FixedSizeBinaryArray::from(values);
871 assert_eq!(array.len(), 4);
872 assert_eq!(array.null_count(), 0);
873 assert_eq!(array.logical_null_count(), 0);
874 assert_eq!(array.value(0), b"one");
875 assert_eq!(array.value(1), b"two");
876 assert_eq!(array.value(2), b"six");
877 assert_eq!(array.value(3), b"ten");
878 assert!(!array.is_null(0));
879 assert!(!array.is_null(1));
880 assert!(!array.is_null(2));
881 assert!(!array.is_null(3));
882 }
883
884 #[test]
885 #[should_panic(expected = "Nested array size mismatch: one is 3, and the other is 5")]
886 fn test_fixed_size_binary_array_from_vec_incorrect_length() {
887 let values = vec!["one".as_bytes(), b"two", b"three", b"four"];
888 let _ = FixedSizeBinaryArray::from(values);
889 }
890
891 #[test]
892 fn test_fixed_size_binary_array_from_opt_vec() {
893 let values = vec![
894 Some("one".as_bytes()),
895 Some(b"two"),
896 None,
897 Some(b"six"),
898 Some(b"ten"),
899 ];
900 let array = FixedSizeBinaryArray::from(values);
901 assert_eq!(array.len(), 5);
902 assert_eq!(array.value(0), b"one");
903 assert_eq!(array.value(1), b"two");
904 assert_eq!(array.value(3), b"six");
905 assert_eq!(array.value(4), b"ten");
906 assert!(!array.is_null(0));
907 assert!(!array.is_null(1));
908 assert!(array.is_null(2));
909 assert!(!array.is_null(3));
910 assert!(!array.is_null(4));
911 }
912
913 #[test]
914 #[should_panic(expected = "Nested array size mismatch: one is 3, and the other is 5")]
915 fn test_fixed_size_binary_array_from_opt_vec_incorrect_length() {
916 let values = vec![
917 Some("one".as_bytes()),
918 Some(b"two"),
919 None,
920 Some(b"three"),
921 Some(b"four"),
922 ];
923 let _ = FixedSizeBinaryArray::from(values);
924 }
925
926 #[test]
927 fn fixed_size_binary_array_all_null() {
928 let data = vec![None] as Vec<Option<String>>;
929 let array =
930 FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.into_iter(), 0).unwrap();
931 array
932 .into_data()
933 .validate_full()
934 .expect("All null array has valid array data");
935 }
936
937 #[test]
938 fn fixed_size_binary_array_all_null_in_batch_with_schema() {
940 let schema = Schema::new(vec![Field::new("a", DataType::FixedSizeBinary(2), true)]);
941
942 let none_option: Option<[u8; 2]> = None;
943 let item = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
944 vec![none_option, none_option, none_option].into_iter(),
945 2,
946 )
947 .unwrap();
948
949 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(item)]).unwrap();
951 }
952
953 #[test]
954 #[should_panic(
955 expected = "Trying to access an element at index 4 from a FixedSizeBinaryArray of length 3"
956 )]
957 fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
958 let values = vec![Some("one".as_bytes()), Some(b"two"), None];
959 let array = FixedSizeBinaryArray::from(values);
960
961 array.value(4);
962 }
963
964 #[test]
965 fn test_constructors() {
966 let buffer = Buffer::from_vec(vec![0_u8; 10]);
967 let a = FixedSizeBinaryArray::new(2, buffer.clone(), None);
968 assert_eq!(a.len(), 5);
969
970 let nulls = NullBuffer::new_null(5);
971 FixedSizeBinaryArray::new(2, buffer.clone(), Some(nulls));
972
973 let a = FixedSizeBinaryArray::new(3, buffer.clone(), None);
974 assert_eq!(a.len(), 3);
975
976 let nulls = NullBuffer::new_null(3);
977 FixedSizeBinaryArray::new(3, buffer.clone(), Some(nulls));
978
979 let err = FixedSizeBinaryArray::try_new(-1, buffer.clone(), None).unwrap_err();
980
981 assert_eq!(
982 err.to_string(),
983 "Invalid argument error: Size cannot be negative, got -1"
984 );
985
986 let nulls = NullBuffer::new_null(3);
987 let err = FixedSizeBinaryArray::try_new(2, buffer, Some(nulls)).unwrap_err();
988 assert_eq!(err.to_string(), "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3");
989 }
990}