use libduckdb_sys::duckdb_vector;
use crate::interval::DuckInterval;
use crate::vector::complex::StructVector;
use crate::vector::VectorReader;
pub struct StructReader {
vector: duckdb_vector,
fields: Vec<VectorReader>,
}
impl StructReader {
pub unsafe fn new(vector: duckdb_vector, field_count: usize, row_count: usize) -> Self {
let mut fields = Vec::with_capacity(field_count);
for idx in 0..field_count {
fields.push(unsafe { StructVector::field_reader(vector, idx, row_count) });
}
Self { vector, fields }
}
#[mutants::skip]
#[must_use]
#[inline]
pub fn field_count(&self) -> usize {
self.fields.len()
}
#[must_use]
#[inline]
pub fn field(&self, field_idx: usize) -> &VectorReader {
&self.fields[field_idx]
}
#[must_use]
#[inline]
pub unsafe fn child_vector(&self, field_idx: usize) -> duckdb_vector {
unsafe { StructVector::get_child(self.vector, field_idx) }
}
#[inline]
pub unsafe fn is_valid(&self, row: usize, field_idx: usize) -> bool {
unsafe { self.fields[field_idx].is_valid(row) }
}
#[inline]
pub unsafe fn read_bool(&self, row: usize, field_idx: usize) -> bool {
unsafe { self.fields[field_idx].read_bool(row) }
}
#[inline]
pub unsafe fn read_str(&self, row: usize, field_idx: usize) -> &str {
unsafe { self.fields[field_idx].read_str(row) }
}
#[inline]
pub unsafe fn read_i8(&self, row: usize, field_idx: usize) -> i8 {
unsafe { self.fields[field_idx].read_i8(row) }
}
#[inline]
pub unsafe fn read_i16(&self, row: usize, field_idx: usize) -> i16 {
unsafe { self.fields[field_idx].read_i16(row) }
}
#[inline]
pub unsafe fn read_i32(&self, row: usize, field_idx: usize) -> i32 {
unsafe { self.fields[field_idx].read_i32(row) }
}
#[inline]
pub unsafe fn read_i64(&self, row: usize, field_idx: usize) -> i64 {
unsafe { self.fields[field_idx].read_i64(row) }
}
#[inline]
pub unsafe fn read_i128(&self, row: usize, field_idx: usize) -> i128 {
unsafe { self.fields[field_idx].read_i128(row) }
}
#[inline]
pub unsafe fn read_u8(&self, row: usize, field_idx: usize) -> u8 {
unsafe { self.fields[field_idx].read_u8(row) }
}
#[inline]
pub unsafe fn read_u16(&self, row: usize, field_idx: usize) -> u16 {
unsafe { self.fields[field_idx].read_u16(row) }
}
#[inline]
pub unsafe fn read_u32(&self, row: usize, field_idx: usize) -> u32 {
unsafe { self.fields[field_idx].read_u32(row) }
}
#[inline]
pub unsafe fn read_u64(&self, row: usize, field_idx: usize) -> u64 {
unsafe { self.fields[field_idx].read_u64(row) }
}
#[inline]
pub unsafe fn read_f32(&self, row: usize, field_idx: usize) -> f32 {
unsafe { self.fields[field_idx].read_f32(row) }
}
#[inline]
pub unsafe fn read_f64(&self, row: usize, field_idx: usize) -> f64 {
unsafe { self.fields[field_idx].read_f64(row) }
}
#[inline]
pub unsafe fn read_interval(&self, row: usize, field_idx: usize) -> DuckInterval {
unsafe { self.fields[field_idx].read_interval(row) }
}
#[inline]
pub unsafe fn read_date(&self, row: usize, field_idx: usize) -> i32 {
unsafe { self.fields[field_idx].read_date(row) }
}
#[inline]
pub unsafe fn read_timestamp(&self, row: usize, field_idx: usize) -> i64 {
unsafe { self.fields[field_idx].read_timestamp(row) }
}
#[inline]
pub unsafe fn read_time(&self, row: usize, field_idx: usize) -> i64 {
unsafe { self.fields[field_idx].read_time(row) }
}
#[inline]
pub unsafe fn read_blob(&self, row: usize, field_idx: usize) -> &[u8] {
unsafe { self.fields[field_idx].read_blob(row) }
}
#[inline]
pub unsafe fn read_uuid(&self, row: usize, field_idx: usize) -> i128 {
unsafe { self.fields[field_idx].read_uuid(row) }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn struct_reader_field_count() {
let sr = StructReader {
vector: std::ptr::null_mut(),
fields: Vec::new(),
};
assert_eq!(sr.field_count(), 0);
}
#[test]
fn size_of_struct_reader() {
assert_eq!(
std::mem::size_of::<StructReader>(),
4 * std::mem::size_of::<usize>() );
}
}