1mod visitor;
5
6use std::any::Any;
7use std::fmt::Debug;
8use std::fmt::Formatter;
9use std::hash::Hash;
10use std::hash::Hasher;
11use std::ops::Deref;
12use std::ops::Range;
13use std::sync::Arc;
14
15pub use visitor::*;
16use vortex_buffer::ByteBuffer;
17use vortex_dtype::DType;
18use vortex_dtype::Nullability;
19use vortex_error::VortexExpect;
20use vortex_error::VortexResult;
21use vortex_error::vortex_ensure;
22use vortex_error::vortex_err;
23use vortex_error::vortex_panic;
24use vortex_mask::Mask;
25
26use crate::AnyCanonical;
27use crate::ArrayEq;
28use crate::ArrayHash;
29use crate::Canonical;
30use crate::DynArrayEq;
31use crate::DynArrayHash;
32use crate::ExecutionCtx;
33use crate::LEGACY_SESSION;
34use crate::VortexSessionExecute;
35use crate::arrays::BoolVTable;
36use crate::arrays::ConstantVTable;
37use crate::arrays::DictArray;
38use crate::arrays::FilterArray;
39use crate::arrays::NullVTable;
40use crate::arrays::PrimitiveVTable;
41use crate::arrays::ScalarFnVTable;
42use crate::arrays::SliceArray;
43use crate::arrays::VarBinVTable;
44use crate::arrays::VarBinViewVTable;
45use crate::buffer::BufferHandle;
46use crate::builders::ArrayBuilder;
47use crate::compute;
48use crate::expr::ReduceNode;
49use crate::expr::ReduceNodeRef;
50use crate::expr::ScalarFn;
51use crate::expr::stats::Precision;
52use crate::expr::stats::Stat;
53use crate::expr::stats::StatsProviderExt;
54use crate::hash;
55use crate::matcher::Matcher;
56use crate::optimizer::ArrayOptimizer;
57use crate::scalar::Scalar;
58use crate::stats::StatsSetRef;
59use crate::validity::Validity;
60use crate::vtable::ArrayId;
61use crate::vtable::ArrayVTableExt;
62use crate::vtable::BaseArrayVTable;
63use crate::vtable::DynVTable;
64use crate::vtable::OperationsVTable;
65use crate::vtable::VTable;
66use crate::vtable::ValidityVTable;
67use crate::vtable::VisitorVTable;
68
69pub trait Array:
71 'static
72 + private::Sealed
73 + Send
74 + Sync
75 + Debug
76 + DynArrayEq
77 + DynArrayHash
78 + ArrayVisitor
79 + ReduceNode
80{
81 fn as_any(&self) -> &dyn Any;
83
84 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
86
87 fn to_array(&self) -> ArrayRef;
89
90 fn len(&self) -> usize;
92
93 fn is_empty(&self) -> bool {
95 self.len() == 0
96 }
97
98 fn dtype(&self) -> &DType;
100
101 fn vtable(&self) -> &dyn DynVTable;
103
104 fn encoding_id(&self) -> ArrayId;
106
107 fn slice(&self, range: Range<usize>) -> VortexResult<ArrayRef>;
109
110 fn filter(&self, mask: Mask) -> VortexResult<ArrayRef>;
112
113 fn take(&self, indices: ArrayRef) -> VortexResult<ArrayRef>;
115
116 fn scalar_at(&self, index: usize) -> VortexResult<Scalar>;
120
121 fn is_valid(&self, index: usize) -> VortexResult<bool>;
123
124 fn is_invalid(&self, index: usize) -> VortexResult<bool>;
126
127 fn all_valid(&self) -> VortexResult<bool>;
132
133 fn all_invalid(&self) -> VortexResult<bool>;
138
139 fn valid_count(&self) -> VortexResult<usize>;
141
142 fn invalid_count(&self) -> VortexResult<usize>;
144
145 fn validity(&self) -> VortexResult<Validity>;
147
148 fn validity_mask(&self) -> VortexResult<Mask>;
150
151 fn to_canonical(&self) -> VortexResult<Canonical>;
153
154 fn append_to_builder(
158 &self,
159 builder: &mut dyn ArrayBuilder,
160 ctx: &mut ExecutionCtx,
161 ) -> VortexResult<()>;
162
163 fn statistics(&self) -> StatsSetRef<'_>;
166
167 fn with_children(&self, children: Vec<ArrayRef>) -> VortexResult<ArrayRef>;
169}
170
171impl Array for Arc<dyn Array> {
172 #[inline]
173 fn as_any(&self) -> &dyn Any {
174 Array::as_any(self.as_ref())
175 }
176
177 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
178 self
179 }
180
181 #[inline]
182 fn to_array(&self) -> ArrayRef {
183 self.clone()
184 }
185
186 #[inline]
187 fn len(&self) -> usize {
188 self.as_ref().len()
189 }
190
191 #[inline]
192 fn dtype(&self) -> &DType {
193 self.as_ref().dtype()
194 }
195
196 fn vtable(&self) -> &dyn DynVTable {
197 self.as_ref().vtable()
198 }
199
200 #[inline]
201 fn encoding_id(&self) -> ArrayId {
202 self.as_ref().encoding_id()
203 }
204
205 #[inline]
206 fn slice(&self, range: Range<usize>) -> VortexResult<ArrayRef> {
207 self.as_ref().slice(range)
208 }
209
210 fn filter(&self, mask: Mask) -> VortexResult<ArrayRef> {
211 self.as_ref().filter(mask)
212 }
213
214 fn take(&self, indices: ArrayRef) -> VortexResult<ArrayRef> {
215 self.as_ref().take(indices)
216 }
217
218 #[inline]
219 fn scalar_at(&self, index: usize) -> VortexResult<Scalar> {
220 self.as_ref().scalar_at(index)
221 }
222
223 #[inline]
224 fn is_valid(&self, index: usize) -> VortexResult<bool> {
225 self.as_ref().is_valid(index)
226 }
227
228 #[inline]
229 fn is_invalid(&self, index: usize) -> VortexResult<bool> {
230 self.as_ref().is_invalid(index)
231 }
232
233 #[inline]
234 fn all_valid(&self) -> VortexResult<bool> {
235 self.as_ref().all_valid()
236 }
237
238 #[inline]
239 fn all_invalid(&self) -> VortexResult<bool> {
240 self.as_ref().all_invalid()
241 }
242
243 #[inline]
244 fn valid_count(&self) -> VortexResult<usize> {
245 self.as_ref().valid_count()
246 }
247
248 #[inline]
249 fn invalid_count(&self) -> VortexResult<usize> {
250 self.as_ref().invalid_count()
251 }
252
253 #[inline]
254 fn validity(&self) -> VortexResult<Validity> {
255 self.as_ref().validity()
256 }
257
258 #[inline]
259 fn validity_mask(&self) -> VortexResult<Mask> {
260 self.as_ref().validity_mask()
261 }
262
263 fn to_canonical(&self) -> VortexResult<Canonical> {
264 self.as_ref().to_canonical()
265 }
266
267 fn append_to_builder(
268 &self,
269 builder: &mut dyn ArrayBuilder,
270 ctx: &mut ExecutionCtx,
271 ) -> VortexResult<()> {
272 self.as_ref().append_to_builder(builder, ctx)
273 }
274
275 fn statistics(&self) -> StatsSetRef<'_> {
276 self.as_ref().statistics()
277 }
278
279 fn with_children(&self, children: Vec<ArrayRef>) -> VortexResult<ArrayRef> {
280 self.as_ref().with_children(children)
281 }
282}
283
284pub type ArrayRef = Arc<dyn Array>;
286
287impl ToOwned for dyn Array {
288 type Owned = ArrayRef;
289
290 fn to_owned(&self) -> Self::Owned {
291 self.to_array()
292 }
293}
294
295impl dyn Array + '_ {
296 pub fn is<M: Matcher>(&self) -> bool {
298 M::matches(self)
299 }
300
301 pub fn as_<M: Matcher>(&self) -> M::Match<'_> {
303 self.as_opt::<M>().vortex_expect("Failed to downcast")
304 }
305
306 pub fn as_opt<M: Matcher>(&self) -> Option<M::Match<'_>> {
308 M::try_match(self)
309 }
310
311 pub fn try_into<V: VTable>(self: Arc<Self>) -> Result<V::Array, Arc<Self>> {
313 match self.is::<V>() {
314 true => {
315 let arc = self
316 .as_any_arc()
317 .downcast::<ArrayAdapter<V>>()
318 .map_err(|_| vortex_err!("failed to downcast"))
319 .vortex_expect("Failed to downcast");
320 Ok(match Arc::try_unwrap(arc) {
321 Ok(array) => array.0,
322 Err(arc) => arc.deref().0.clone(),
323 })
324 }
325 false => Err(self),
326 }
327 }
328
329 pub fn as_constant(&self) -> Option<Scalar> {
330 self.as_opt::<ConstantVTable>().map(|a| a.scalar().clone())
331 }
332
333 pub fn nbytes(&self) -> u64 {
335 let mut nbytes = 0;
336 for array in self.depth_first_traversal() {
337 for buffer in array.buffers() {
338 nbytes += buffer.len() as u64;
339 }
340 }
341 nbytes
342 }
343
344 pub fn is_arrow(&self) -> bool {
346 self.is::<NullVTable>()
347 || self.is::<BoolVTable>()
348 || self.is::<PrimitiveVTable>()
349 || self.is::<VarBinVTable>()
350 || self.is::<VarBinViewVTable>()
351 }
352
353 pub fn is_canonical(&self) -> bool {
355 self.is::<AnyCanonical>()
356 }
357}
358
359pub trait IntoArray {
361 fn into_array(self) -> ArrayRef;
362}
363
364impl IntoArray for ArrayRef {
365 fn into_array(self) -> ArrayRef {
366 self
367 }
368}
369
370mod private {
371 use super::*;
372
373 pub trait Sealed {}
374
375 impl<V: VTable> Sealed for ArrayAdapter<V> {}
376 impl Sealed for Arc<dyn Array> {}
377}
378
379#[repr(transparent)]
386pub struct ArrayAdapter<V: VTable>(V::Array);
387
388impl<V: VTable> ArrayAdapter<V> {
389 pub fn as_inner(&self) -> &V::Array {
391 &self.0
392 }
393}
394
395impl<V: VTable> Debug for ArrayAdapter<V> {
396 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
397 self.0.fmt(f)
398 }
399}
400
401impl<V: VTable> ReduceNode for ArrayAdapter<V> {
402 fn as_any(&self) -> &dyn Any {
403 self
404 }
405
406 fn node_dtype(&self) -> VortexResult<DType> {
407 Ok(<V::ArrayVTable as BaseArrayVTable<V>>::dtype(&self.0).clone())
408 }
409
410 fn scalar_fn(&self) -> Option<&ScalarFn> {
411 self.0.as_opt::<ScalarFnVTable>().map(|a| a.scalar_fn())
412 }
413
414 fn child(&self, idx: usize) -> ReduceNodeRef {
415 self.nth_child(idx)
416 .unwrap_or_else(|| vortex_panic!("Child index out of bounds: {}", idx))
417 }
418
419 fn child_count(&self) -> usize {
420 self.nchildren()
421 }
422}
423
424impl<V: VTable> Array for ArrayAdapter<V> {
425 fn as_any(&self) -> &dyn Any {
426 self
427 }
428
429 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
430 self
431 }
432
433 fn to_array(&self) -> ArrayRef {
434 Arc::new(ArrayAdapter::<V>(self.0.clone()))
435 }
436
437 fn len(&self) -> usize {
438 <V::ArrayVTable as BaseArrayVTable<V>>::len(&self.0)
439 }
440
441 fn dtype(&self) -> &DType {
442 <V::ArrayVTable as BaseArrayVTable<V>>::dtype(&self.0)
443 }
444
445 fn vtable(&self) -> &dyn DynVTable {
446 V::vtable()
447 }
448
449 fn encoding_id(&self) -> ArrayId {
450 V::id(&self.0)
451 }
452
453 fn slice(&self, range: Range<usize>) -> VortexResult<ArrayRef> {
454 let start = range.start;
455 let stop = range.end;
456
457 if start == 0 && stop == self.len() {
458 return Ok(self.to_array());
459 }
460
461 vortex_ensure!(
462 start <= self.len(),
463 "OutOfBounds: start {start} > length {}",
464 self.len()
465 );
466 vortex_ensure!(
467 stop <= self.len(),
468 "OutOfBounds: stop {stop} > length {}",
469 self.len()
470 );
471
472 vortex_ensure!(start <= stop, "start ({start}) must be <= stop ({stop})");
473
474 if start == stop {
475 return Ok(Canonical::empty(self.dtype()).into_array());
476 }
477
478 let sliced = SliceArray::try_new(self.to_array(), range)?
479 .into_array()
480 .optimize()?;
481
482 if !sliced.is::<ConstantVTable>() {
484 self.statistics().with_iter(|iter| {
485 sliced.statistics().inherit(iter.filter(|(stat, value)| {
486 matches!(
487 stat,
488 Stat::IsConstant | Stat::IsSorted | Stat::IsStrictSorted
489 ) && value.as_ref().as_exact().is_some_and(|v| {
490 Scalar::try_new(DType::Bool(Nullability::NonNullable), Some(v.clone()))
491 .vortex_expect("A stat that was expected to be a boolean stat was not")
492 .as_bool()
493 .value()
494 .unwrap_or_default()
495 })
496 }));
497 });
498 }
499
500 Ok(sliced)
501 }
502
503 fn filter(&self, mask: Mask) -> VortexResult<ArrayRef> {
504 FilterArray::try_new(self.to_array(), mask)?
505 .into_array()
506 .optimize()
507 }
508
509 fn take(&self, indices: ArrayRef) -> VortexResult<ArrayRef> {
510 DictArray::try_new(indices, self.to_array())?
511 .into_array()
512 .optimize()
513 }
514
515 fn scalar_at(&self, index: usize) -> VortexResult<Scalar> {
516 vortex_ensure!(index < self.len(), OutOfBounds: index, 0, self.len());
517 if self.is_invalid(index)? {
518 return Ok(Scalar::null(self.dtype().clone()));
519 }
520 let scalar = <V::OperationsVTable as OperationsVTable<V>>::scalar_at(&self.0, index)?;
521 vortex_ensure!(self.dtype() == scalar.dtype(), "Scalar dtype mismatch");
522 Ok(scalar)
523 }
524
525 fn is_valid(&self, index: usize) -> VortexResult<bool> {
526 vortex_ensure!(index < self.len(), OutOfBounds: index, 0, self.len());
527 match self.validity()? {
528 Validity::NonNullable | Validity::AllValid => Ok(true),
529 Validity::AllInvalid => Ok(false),
530 Validity::Array(a) => a
531 .scalar_at(index)?
532 .as_bool()
533 .value()
534 .ok_or_else(|| vortex_err!("validity value at index {} is null", index)),
535 }
536 }
537
538 fn is_invalid(&self, index: usize) -> VortexResult<bool> {
539 Ok(!self.is_valid(index)?)
540 }
541
542 fn all_valid(&self) -> VortexResult<bool> {
543 match self.validity()? {
544 Validity::NonNullable | Validity::AllValid => Ok(true),
545 Validity::AllInvalid => Ok(false),
546 Validity::Array(a) => Ok(a.statistics().compute_min::<bool>().unwrap_or(false)),
547 }
548 }
549
550 fn all_invalid(&self) -> VortexResult<bool> {
551 match self.validity()? {
552 Validity::NonNullable | Validity::AllValid => Ok(false),
553 Validity::AllInvalid => Ok(true),
554 Validity::Array(a) => Ok(!a.statistics().compute_max::<bool>().unwrap_or(true)),
555 }
556 }
557
558 fn valid_count(&self) -> VortexResult<usize> {
559 if let Some(Precision::Exact(invalid_count)) =
560 self.statistics().get_as::<usize>(Stat::NullCount)
561 {
562 return Ok(self.len() - invalid_count);
563 }
564
565 let count = match self.validity()? {
566 Validity::NonNullable | Validity::AllValid => self.len(),
567 Validity::AllInvalid => 0,
568 Validity::Array(a) => {
569 let sum = compute::sum(&a)?;
570 sum.as_primitive()
571 .as_::<usize>()
572 .ok_or_else(|| vortex_err!("sum of validity array is null"))?
573 }
574 };
575 vortex_ensure!(count <= self.len(), "Valid count exceeds array length");
576
577 self.statistics()
578 .set(Stat::NullCount, Precision::exact(self.len() - count));
579
580 Ok(count)
581 }
582
583 fn invalid_count(&self) -> VortexResult<usize> {
584 Ok(self.len() - self.valid_count()?)
585 }
586
587 fn validity(&self) -> VortexResult<Validity> {
588 if self.dtype().is_nullable() {
589 let validity = <V::ValidityVTable as ValidityVTable<V>>::validity(&self.0)?;
590 if let Validity::Array(array) = &validity {
591 vortex_ensure!(array.len() == self.len(), "Validity array length mismatch");
592 vortex_ensure!(
593 matches!(array.dtype(), DType::Bool(Nullability::NonNullable)),
594 "Validity array is not non-nullable boolean: {}",
595 self.encoding_id(),
596 );
597 }
598 Ok(validity)
599 } else {
600 Ok(Validity::NonNullable)
601 }
602 }
603
604 fn validity_mask(&self) -> VortexResult<Mask> {
605 match self.validity()? {
606 Validity::NonNullable | Validity::AllValid => Ok(Mask::new_true(self.len())),
607 Validity::AllInvalid => Ok(Mask::new_false(self.len())),
608 Validity::Array(a) => a.try_to_mask_fill_null_false(),
609 }
610 }
611
612 fn to_canonical(&self) -> VortexResult<Canonical> {
613 self.to_array()
614 .execute(&mut LEGACY_SESSION.create_execution_ctx())
615 }
616
617 fn append_to_builder(
618 &self,
619 builder: &mut dyn ArrayBuilder,
620 ctx: &mut ExecutionCtx,
621 ) -> VortexResult<()> {
622 if builder.dtype() != self.dtype() {
623 vortex_panic!(
624 "Builder dtype mismatch: expected {}, got {}",
625 self.dtype(),
626 builder.dtype(),
627 );
628 }
629 let len = builder.len();
630
631 V::append_to_builder(&self.0, builder, ctx)?;
632
633 assert_eq!(
634 len + self.len(),
635 builder.len(),
636 "Builder length mismatch after writing array for encoding {}",
637 self.encoding_id(),
638 );
639 Ok(())
640 }
641
642 fn statistics(&self) -> StatsSetRef<'_> {
643 <V::ArrayVTable as BaseArrayVTable<V>>::stats(&self.0)
644 }
645
646 fn with_children(&self, children: Vec<ArrayRef>) -> VortexResult<ArrayRef> {
647 let mut this = self.0.clone();
648 V::with_children(&mut this, children)?;
649 Ok(this.into_array())
650 }
651}
652
653impl<V: VTable> ArrayHash for ArrayAdapter<V> {
654 fn array_hash<H: Hasher>(&self, state: &mut H, precision: hash::Precision) {
655 self.0.encoding_id().hash(state);
656 <V::ArrayVTable as BaseArrayVTable<V>>::array_hash(&self.0, state, precision);
657 }
658}
659
660impl<V: VTable> ArrayEq for ArrayAdapter<V> {
661 fn array_eq(&self, other: &Self, precision: hash::Precision) -> bool {
662 <V::ArrayVTable as BaseArrayVTable<V>>::array_eq(&self.0, &other.0, precision)
663 }
664}
665
666impl<V: VTable> ArrayVisitor for ArrayAdapter<V> {
667 fn children(&self) -> Vec<ArrayRef> {
668 struct ChildrenCollector {
669 children: Vec<ArrayRef>,
670 }
671
672 impl ArrayChildVisitorUnnamed for ChildrenCollector {
673 fn visit_child(&mut self, array: &ArrayRef) {
674 self.children.push(array.clone());
675 }
676 }
677
678 let mut collector = ChildrenCollector {
679 children: Vec::new(),
680 };
681 <V::VisitorVTable as VisitorVTable<V>>::visit_children_unnamed(&self.0, &mut collector);
682 collector.children
683 }
684
685 fn nchildren(&self) -> usize {
686 <V::VisitorVTable as VisitorVTable<V>>::nchildren(&self.0)
687 }
688
689 fn nth_child(&self, idx: usize) -> Option<ArrayRef> {
690 <V::VisitorVTable as VisitorVTable<V>>::nth_child(&self.0, idx)
691 }
692
693 fn children_names(&self) -> Vec<String> {
694 struct ChildNameCollector {
695 names: Vec<String>,
696 }
697
698 impl ArrayChildVisitor for ChildNameCollector {
699 fn visit_child(&mut self, name: &str, _array: &ArrayRef) {
700 self.names.push(name.to_string());
701 }
702 }
703
704 let mut collector = ChildNameCollector { names: Vec::new() };
705 <V::VisitorVTable as VisitorVTable<V>>::visit_children(&self.0, &mut collector);
706 collector.names
707 }
708
709 fn named_children(&self) -> Vec<(String, ArrayRef)> {
710 struct NamedChildrenCollector {
711 children: Vec<(String, ArrayRef)>,
712 }
713
714 impl ArrayChildVisitor for NamedChildrenCollector {
715 fn visit_child(&mut self, name: &str, array: &ArrayRef) {
716 self.children.push((name.to_string(), array.to_array()));
717 }
718 }
719
720 let mut collector = NamedChildrenCollector {
721 children: Vec::new(),
722 };
723
724 <V::VisitorVTable as VisitorVTable<V>>::visit_children(&self.0, &mut collector);
725 collector.children
726 }
727
728 fn buffers(&self) -> Vec<ByteBuffer> {
729 struct BufferCollector {
730 buffers: Vec<ByteBuffer>,
731 }
732
733 impl ArrayBufferVisitor for BufferCollector {
734 fn visit_buffer_handle(&mut self, _name: &str, handle: &BufferHandle) {
735 self.buffers.push(handle.to_host_sync());
736 }
737 }
738
739 let mut collector = BufferCollector {
740 buffers: Vec::new(),
741 };
742 <V::VisitorVTable as VisitorVTable<V>>::visit_buffers(&self.0, &mut collector);
743 collector.buffers
744 }
745
746 fn buffer_handles(&self) -> Vec<BufferHandle> {
747 struct BufferHandleCollector {
748 handles: Vec<BufferHandle>,
749 }
750
751 impl ArrayBufferVisitor for BufferHandleCollector {
752 fn visit_buffer_handle(&mut self, _name: &str, handle: &BufferHandle) {
753 self.handles.push(handle.clone());
754 }
755 }
756
757 let mut collector = BufferHandleCollector {
758 handles: Vec::new(),
759 };
760 <V::VisitorVTable as VisitorVTable<V>>::visit_buffers(&self.0, &mut collector);
761 collector.handles
762 }
763
764 fn buffer_names(&self) -> Vec<String> {
765 <V::VisitorVTable as VisitorVTable<V>>::buffer_names(&self.0)
766 }
767
768 fn named_buffers(&self) -> Vec<(String, BufferHandle)> {
769 struct NamedBufferCollector {
770 buffers: Vec<(String, BufferHandle)>,
771 }
772
773 impl ArrayBufferVisitor for NamedBufferCollector {
774 fn visit_buffer_handle(&mut self, name: &str, handle: &BufferHandle) {
775 self.buffers.push((name.to_string(), handle.clone()));
776 }
777 }
778
779 let mut collector = NamedBufferCollector {
780 buffers: Vec::new(),
781 };
782 <V::VisitorVTable as VisitorVTable<V>>::visit_buffers(&self.0, &mut collector);
783 collector.buffers
784 }
785
786 fn nbuffers(&self) -> usize {
787 <V::VisitorVTable as VisitorVTable<V>>::nbuffers(&self.0)
788 }
789
790 fn metadata(&self) -> VortexResult<Option<Vec<u8>>> {
791 V::serialize(V::metadata(&self.0)?)
792 }
793
794 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
795 match V::metadata(&self.0) {
796 Err(e) => write!(f, "<serde error: {e}>"),
797 Ok(metadata) => Debug::fmt(&metadata, f),
798 }
799 }
800
801 fn is_host(&self) -> bool {
802 for array in self.depth_first_traversal() {
803 if !array.buffer_handles().iter().all(BufferHandle::is_on_host) {
804 return false;
805 }
806 }
807
808 true
809 }
810}
811
812impl<V: VTable> Matcher for V {
814 type Match<'a> = &'a V::Array;
815
816 fn matches(array: &dyn Array) -> bool {
817 Array::as_any(array).is::<ArrayAdapter<V>>()
818 }
819
820 fn try_match<'a>(array: &'a dyn Array) -> Option<Self::Match<'a>> {
821 Array::as_any(array)
822 .downcast_ref::<ArrayAdapter<V>>()
823 .map(|array_adapter| &array_adapter.0)
824 }
825}