#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(missing_copy_implementations)]
use crate::cassandra::data_type::ConstDataType;
use crate::cassandra::error::*;
use crate::cassandra::row::Row;
use crate::cassandra::util::{Protected, ProtectedInner};
use crate::cassandra::value::ValueType;
use crate::cassandra_sys::cass_false;
use crate::cassandra_sys::cass_iterator_free;
use crate::cassandra_sys::cass_iterator_from_result;
use crate::cassandra_sys::cass_iterator_get_row;
use crate::cassandra_sys::cass_iterator_next;
use crate::cassandra_sys::cass_result_column_count;
use crate::cassandra_sys::cass_result_column_data_type;
use crate::cassandra_sys::cass_result_column_name;
use crate::cassandra_sys::cass_result_column_type;
use crate::cassandra_sys::cass_result_first_row;
use crate::cassandra_sys::cass_result_free;
use crate::cassandra_sys::cass_result_has_more_pages;
use crate::cassandra_sys::cass_result_paging_state_token;
use crate::cassandra_sys::cass_result_row_count;
use crate::cassandra_sys::cass_true;
use crate::cassandra_sys::CassIterator as _CassIterator;
use crate::cassandra_sys::CassResult as _CassResult;
use std::ffi::CString;
use std::fmt;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::marker::PhantomData;
use std::mem;
use std::slice;
use std::str;
pub struct CassResult(*const _CassResult);
unsafe impl Sync for CassResult {}
unsafe impl Send for CassResult {}
impl ProtectedInner<*const _CassResult> for CassResult {
fn inner(&self) -> *const _CassResult {
self.0
}
}
impl Protected<*const _CassResult> for CassResult {
fn build(inner: *const _CassResult) -> Self {
if inner.is_null() {
panic!("Unexpected null pointer")
};
CassResult(inner)
}
}
impl Debug for CassResult {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
writeln!(f, "Result row count: {:?}", self.row_count())?;
for row in self.iter() {
writeln!(f, "{:?}", row)?;
}
Ok(())
}
}
impl Display for CassResult {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
writeln!(f, "Result row count: {}", self.row_count())?;
for row in self.iter() {
writeln!(f, "{}", row)?;
}
Ok(())
}
}
impl Drop for CassResult {
fn drop(&mut self) {
unsafe { cass_result_free(self.0) }
}
}
impl CassResult {
pub fn row_count(&self) -> u64 {
unsafe { cass_result_row_count(self.0) as u64 }
}
pub fn column_count(&self) -> u64 {
unsafe { cass_result_column_count(self.0) as u64 }
}
pub fn column_name(&self, index: usize) -> Result<&str> {
let mut name = std::ptr::null();
let mut name_length = 0;
unsafe {
cass_result_column_name(self.0, index, &mut name, &mut name_length)
.to_result(())
.and_then(|_| {
let slice = slice::from_raw_parts(name as *const u8, name_length);
Ok(str::from_utf8(slice)?)
})
}
}
pub fn column_type(&self, index: usize) -> ValueType {
unsafe { ValueType::build(cass_result_column_type(self.0, index)) }
}
pub fn column_data_type(&self, index: usize) -> ConstDataType {
unsafe { ConstDataType::build(cass_result_column_data_type(self.0, index)) }
}
pub fn first_row(&self) -> Option<Row> {
unsafe {
match self.row_count() {
0 => None,
_ => Some(Row::build(cass_result_first_row(self.0))),
}
}
}
pub fn has_more_pages(&self) -> bool {
unsafe { cass_result_has_more_pages(self.0) == cass_true }
}
pub fn paging_state_token(&self) -> Result<Option<Vec<u8>>> {
if !self.has_more_pages() {
return Ok(None);
}
let mut token_ptr = std::ptr::null();
let mut token_length = 0;
unsafe {
cass_result_paging_state_token(self.0, &mut token_ptr, &mut token_length)
.to_result(())
.map(|_| Some(slice::from_raw_parts(token_ptr as *const u8, token_length).to_vec()))
}
}
pub fn iter(&self) -> ResultIterator {
unsafe {
ResultIterator(
cass_iterator_from_result(self.0),
cass_result_row_count(self.0),
PhantomData,
)
}
}
}
#[derive(Debug)]
pub struct ResultIterator<'a>(pub *mut _CassIterator, usize, PhantomData<&'a CassResult>);
unsafe impl<'a> Send for ResultIterator<'a> {}
impl<'a> Drop for ResultIterator<'a> {
fn drop(&mut self) {
unsafe { cass_iterator_free(self.0) }
}
}
impl<'a> Iterator for ResultIterator<'a> {
type Item = Row<'a>;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
match cass_iterator_next(self.0) {
cass_false => None,
cass_true => Some(self.get_row()),
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.1))
}
}
impl<'a> ResultIterator<'a> {
pub fn get_row(&mut self) -> Row<'a> {
unsafe { Row::build(cass_iterator_get_row(self.0)) }
}
}
impl<'a> IntoIterator for &'a CassResult {
type Item = Row<'a>;
type IntoIter = ResultIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}