Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add proptest strategies for generating Dimension, a bunch of Debug impls, and even some arrow stuff #15

Merged
merged 13 commits into from
Mar 20, 2024
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tiledb/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ name = "tiledb"
path = "src/lib.rs"

[dependencies]
serde_json = "1.0.114"
tiledb-sys = { workspace = true }

[dev-dependencies]
Expand Down
15 changes: 15 additions & 0 deletions tiledb/api/src/array/dimension.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use serde_json::json;
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::Deref;

use crate::context::Context;
use crate::convert::CAPIConverter;
use crate::filter_list::FilterList;
use crate::fn_typed;
use crate::Datatype;
use crate::Result as TileDBResult;

Expand Down Expand Up @@ -100,6 +103,18 @@ impl<'ctx> Dimension<'ctx> {
}
}

impl<'ctx> Debug for Dimension<'ctx> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
let json = json!({
"datatype": format!("{}", self.datatype()),
"domain": fn_typed!(self.domain, self.datatype() => match domain { Ok(x) => format!("{:?}", x), Err(e) => format!("<{}>", e) }),
/* TODO: filters */
"raw": format!("{:p}", *self.raw)
});
write!(f, "{}", json)
}
}

pub struct Builder<'ctx> {
dim: Dimension<'ctx>,
}
Expand Down
25 changes: 23 additions & 2 deletions tiledb/api/src/array/domain.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use serde_json::json;
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::Deref;

use crate::array::{dimension::RawDimension, Dimension};
Expand Down Expand Up @@ -39,7 +41,7 @@ impl<'ctx> Domain<'ctx> {
Domain { context, raw }
}

pub fn ndim(&self) -> u32 {
pub fn ndim(&self) -> usize {
let mut ndim: u32 = out_ptr!();
let c_ret = unsafe {
ffi::tiledb_domain_get_ndim(
Expand All @@ -50,7 +52,7 @@ impl<'ctx> Domain<'ctx> {
};
// the only errors are possible via mis-use of the C API, which Rust prevents
assert_eq!(ffi::TILEDB_OK, c_ret);
ndim
ndim as usize
}

pub fn dimension(&self, idx: usize) -> TileDBResult<Dimension<'ctx>> {
Expand Down Expand Up @@ -85,6 +87,25 @@ impl<'ctx> Domain<'ctx> {
}
}

impl<'ctx> Debug for Domain<'ctx> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
let json = json!({
"dimensions": (0..self.ndim())
.map(|d| {
serde_json::value::Value::String(match self.dimension(d) {
Ok(d) => format!("{:?}", d),
Err(e) => format!("<{}>", e),
})
})
.collect::<Vec<_>>(),
"raw": format!("{:p}", *self.raw)
/* TODO: what other fields? */
});

write!(f, "{}", json)
}
}

pub struct Builder<'ctx> {
domain: Domain<'ctx>,
}
Expand Down
27 changes: 26 additions & 1 deletion tiledb/api/src/array/schema.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use serde_json::json;
use std::convert::TryFrom;
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::Deref;

use crate::array::attribute::RawAttribute;
Expand All @@ -7,7 +9,7 @@ use crate::array::{Attribute, Domain, Layout};
use crate::context::Context;
use crate::Result as TileDBResult;

#[derive(Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
pub enum ArrayType {
Dense,
Sparse,
Expand Down Expand Up @@ -239,6 +241,29 @@ impl<'ctx> Schema<'ctx> {
}
}

impl<'ctx> Debug for Schema<'ctx> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
let json = json!({
"array_type": format!("{:?}", self.array_type()),
"capacity": self.capacity(),
"cell_order": format!("{:?}", self.cell_order()),
"tile_order": format!("{:?}", self.tile_order()),
"allows_duplicates": self.allows_duplicates(),
"domain": match self.domain() {
Ok(d) => format!("{:?}", d),
Err(e) => format!("<{}>", e)
},
"attributes": (0.. self.nattributes()).map(|a| match self.attribute(a) {
Ok(a) => format!("{:?}", a),
Err(e) => format!("<Error retrieving attribute {}: {}>", a, e)
}).collect::<Vec<String>>(),
"version": self.version(),
"raw": format!("{:p}", *self.raw),
});
write!(f, "{}", json)
}
}

pub struct Builder<'ctx> {
schema: Schema<'ctx>,
}
Expand Down
47 changes: 18 additions & 29 deletions tiledb/api/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,31 @@
pub trait CAPISameRepr: Copy + Default {}

impl CAPISameRepr for u8 {}
impl CAPISameRepr for u16 {}
impl CAPISameRepr for u32 {}
impl CAPISameRepr for u64 {}
impl CAPISameRepr for i8 {}
impl CAPISameRepr for i16 {}
impl CAPISameRepr for i32 {}
impl CAPISameRepr for i64 {}
impl CAPISameRepr for f32 {}
impl CAPISameRepr for f64 {}

pub trait CAPIConverter {
type CAPIType: Default + Copy;

fn to_capi(&self) -> Self::CAPIType;
fn to_rust(value: &Self::CAPIType) -> Self;
}

impl CAPIConverter for i32 {
type CAPIType = std::ffi::c_int;

fn to_capi(&self) -> Self::CAPIType {
*self as Self::CAPIType
}

fn to_rust(value: &Self::CAPIType) -> Self {
*value as Self
}
}

impl CAPIConverter for u32 {
type CAPIType = std::ffi::c_uint;

fn to_capi(&self) -> Self::CAPIType {
*self as Self::CAPIType
}

fn to_rust(value: &Self::CAPIType) -> Self {
*value as Self
}
}

impl CAPIConverter for f64 {
type CAPIType = std::ffi::c_double;
impl<T: CAPISameRepr> CAPIConverter for T {
type CAPIType = Self;

fn to_capi(&self) -> Self::CAPIType {
*self as Self::CAPIType
*self
}

fn to_rust(value: &Self::CAPIType) -> Self {
*value as Self
fn to_rust(value: &Self::CAPIType) -> T {
*value
}
}
161 changes: 161 additions & 0 deletions tiledb/api/src/datatype.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#[macro_export]
macro_rules! fn_typed {
($func:ident, $datatype:expr$(, $arg:expr)* => $then:expr) => {{
type Datatype = $crate::Datatype;
match $datatype {
Datatype::Int8 => {
let $func = $func::<i8>();
$then
}
Datatype::Int16 => {
let $func = $func::<i16>();
$then
}
Datatype::Int32 => {
let $func = $func::<i32>();
$then
}
Datatype::Int64 => {
let $func = $func::<i64>();
$then
}
Datatype::UInt8 => {
let $func = $func::<u8>();
$then
}
Datatype::UInt16 => {
let $func = $func::<u16>();
$then
}
Datatype::UInt32 => {
let $func = $func::<u32>();
$then
}
Datatype::UInt64 => {
let $func = $func::<u64>();
$then
}
Datatype::Float32 => {
let $func = $func::<f32>();
$then
}
Datatype::Float64 => {
let $func = $func::<f64>();
$then
}
Datatype::Char => unimplemented!(),
Datatype::StringAscii => unimplemented!(),
Datatype::StringUtf8 => unimplemented!(),
Datatype::StringUtf16 => unimplemented!(),
Datatype::StringUtf32 => unimplemented!(),
Datatype::StringUcs2 => unimplemented!(),
Datatype::StringUcs4 => unimplemented!(),
Datatype::Any => unimplemented!(),
Datatype::DateTimeYear => unimplemented!(),
Datatype::DateTimeMonth => unimplemented!(),
Datatype::DateTimeWeek => unimplemented!(),
Datatype::DateTimeDay => unimplemented!(),
Datatype::DateTimeHour => unimplemented!(),
Datatype::DateTimeMinute => unimplemented!(),
Datatype::DateTimeSecond => unimplemented!(),
Datatype::DateTimeMillisecond => unimplemented!(),
Datatype::DateTimeMicrosecond => unimplemented!(),
Datatype::DateTimeNanosecond => unimplemented!(),
Datatype::DateTimePicosecond => unimplemented!(),
Datatype::DateTimeFemtosecond => unimplemented!(),
Datatype::DateTimeAttosecond => unimplemented!(),
Datatype::TimeHour => unimplemented!(),
Datatype::TimeMinute => unimplemented!(),
Datatype::TimeSecond => unimplemented!(),
Datatype::TimeMillisecond => unimplemented!(),
Datatype::TimeMicrosecond => unimplemented!(),
Datatype::TimeNanosecond => unimplemented!(),
Datatype::TimePicosecond => unimplemented!(),
Datatype::TimeFemtosecond => unimplemented!(),
Datatype::TimeAttosecond => unimplemented!(),
Datatype::Blob => unimplemented!(),
Datatype::Boolean => unimplemented!(),
Datatype::GeometryWkb => unimplemented!(),
Datatype::GeometryWkt => unimplemented!(),
}
}};
($obj:ident.$func:ident, $datatype:expr$(, $arg:expr)* => $then:expr) => {{
type Datatype = $crate::Datatype;
match $datatype {
Datatype::Int8 => {
let $func = $obj.$func::<i8>();
$then
}
Datatype::Int16 => {
let $func = $obj.$func::<i16>();
$then
}
Datatype::Int32 => {
let $func = $obj.$func::<i32>();
$then
}
Datatype::Int64 => {
let $func = $obj.$func::<i64>();
$then
}
Datatype::UInt8 => {
let $func = $obj.$func::<u8>();
$then
}
Datatype::UInt16 => {
let $func = $obj.$func::<u16>();
$then
}
Datatype::UInt32 => {
let $func = $obj.$func::<u32>();
$then
}
Datatype::UInt64 => {
let $func = $obj.$func::<u64>();
$then
}
Datatype::Float32 => {
let $func = $obj.$func::<f32>();
$then
}
Datatype::Float64 => {
let $func = $obj.$func::<f64>();
$then
}
Datatype::Char => unimplemented!(),
Datatype::StringAscii => unimplemented!(),
Datatype::StringUtf8 => unimplemented!(),
Datatype::StringUtf16 => unimplemented!(),
Datatype::StringUtf32 => unimplemented!(),
Datatype::StringUcs2 => unimplemented!(),
Datatype::StringUcs4 => unimplemented!(),
Datatype::Any => unimplemented!(),
Datatype::DateTimeYear => unimplemented!(),
Datatype::DateTimeMonth => unimplemented!(),
Datatype::DateTimeWeek => unimplemented!(),
Datatype::DateTimeDay => unimplemented!(),
Datatype::DateTimeHour => unimplemented!(),
Datatype::DateTimeMinute => unimplemented!(),
Datatype::DateTimeSecond => unimplemented!(),
Datatype::DateTimeMillisecond => unimplemented!(),
Datatype::DateTimeMicrosecond => unimplemented!(),
Datatype::DateTimeNanosecond => unimplemented!(),
Datatype::DateTimePicosecond => unimplemented!(),
Datatype::DateTimeFemtosecond => unimplemented!(),
Datatype::DateTimeAttosecond => unimplemented!(),
Datatype::TimeHour => unimplemented!(),
Datatype::TimeMinute => unimplemented!(),
Datatype::TimeSecond => unimplemented!(),
Datatype::TimeMillisecond => unimplemented!(),
Datatype::TimeMicrosecond => unimplemented!(),
Datatype::TimeNanosecond => unimplemented!(),
Datatype::TimePicosecond => unimplemented!(),
Datatype::TimeFemtosecond => unimplemented!(),
Datatype::TimeAttosecond => unimplemented!(),
Datatype::Blob => unimplemented!(),
Datatype::Boolean => unimplemented!(),
Datatype::GeometryWkb => unimplemented!(),
Datatype::GeometryWkt => unimplemented!(),
}
}};
}
2 changes: 2 additions & 0 deletions tiledb/api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,5 @@ impl Drop for Error {
}
}
}

impl std::error::Error for Error {}
2 changes: 2 additions & 0 deletions tiledb/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
extern crate serde_json;
extern crate tiledb_sys as ffi;

macro_rules! cstring {
Expand All @@ -24,6 +25,7 @@ pub mod array;
pub mod config;
pub mod context;
pub mod convert;
pub mod datatype;
pub mod error;
pub mod filter;
pub mod filter_list;
Expand Down
Loading
Loading