use crate::ArrayBufferVisitor;
use crate::ArrayChildVisitor;
use crate::ArrayChildVisitorUnnamed;
use crate::ArrayRef;
use crate::IntoArray;
use crate::arrays::ConstantArray;
use crate::buffer::BufferHandle;
use crate::validity::Validity;
use crate::vtable::VTable;
#[inline]
pub fn validity_to_child(validity: &Validity, len: usize) -> Option<ArrayRef> {
match validity {
Validity::NonNullable | Validity::AllValid => None,
Validity::AllInvalid => Some(ConstantArray::new(false, len).into_array()),
Validity::Array(array) => Some(array.clone()),
}
}
#[inline]
pub fn validity_nchildren(validity: &Validity) -> usize {
match validity {
Validity::NonNullable | Validity::AllValid => 0,
Validity::AllInvalid | Validity::Array(_) => 1,
}
}
pub trait VisitorVTable<V: VTable> {
fn visit_buffers(array: &V::Array, visitor: &mut dyn ArrayBufferVisitor);
fn nbuffers(array: &V::Array) -> usize {
struct NBuffers(usize);
impl ArrayBufferVisitor for NBuffers {
fn visit_buffer_handle(&mut self, _name: &str, _handle: &BufferHandle) {
self.0 += 1;
}
}
let mut visitor = NBuffers(0);
<V::VisitorVTable as VisitorVTable<V>>::visit_buffers(array, &mut visitor);
visitor.0
}
fn buffer_names(array: &V::Array) -> Vec<String> {
struct BufferNames(Vec<String>);
impl ArrayBufferVisitor for BufferNames {
fn visit_buffer_handle(&mut self, name: &str, _handle: &BufferHandle) {
self.0.push(name.to_string());
}
}
let mut visitor = BufferNames(Vec::new());
<V::VisitorVTable as VisitorVTable<V>>::visit_buffers(array, &mut visitor);
visitor.0
}
fn visit_children(array: &V::Array, visitor: &mut dyn ArrayChildVisitor);
fn visit_children_unnamed(array: &V::Array, visitor: &mut dyn ArrayChildVisitorUnnamed) {
struct UnnamedWrapper<'a>(&'a mut dyn ArrayChildVisitorUnnamed);
impl ArrayChildVisitor for UnnamedWrapper<'_> {
fn visit_child(&mut self, _name: &str, array: &ArrayRef) {
self.0.visit_child(array);
}
}
<V::VisitorVTable as VisitorVTable<V>>::visit_children(array, &mut UnnamedWrapper(visitor));
}
fn nchildren(array: &V::Array) -> usize {
struct NChildren(usize);
impl ArrayChildVisitorUnnamed for NChildren {
fn visit_child(&mut self, _array: &ArrayRef) {
self.0 += 1;
}
}
let mut visitor = NChildren(0);
<V::VisitorVTable as VisitorVTable<V>>::visit_children_unnamed(array, &mut visitor);
visitor.0
}
fn nth_child(array: &V::Array, idx: usize) -> Option<ArrayRef> {
struct NthChildVisitor {
target_idx: usize,
current_idx: usize,
result: Option<ArrayRef>,
}
impl ArrayChildVisitorUnnamed for NthChildVisitor {
fn visit_child(&mut self, array: &ArrayRef) {
if self.current_idx == self.target_idx && self.result.is_none() {
self.result = Some(array.clone());
}
self.current_idx += 1;
}
}
let mut visitor = NthChildVisitor {
target_idx: idx,
current_idx: 0,
result: None,
};
<V::VisitorVTable as VisitorVTable<V>>::visit_children_unnamed(array, &mut visitor);
visitor.result
}
}