cassandra_cpp/cassandra/
result.rs1#![allow(non_camel_case_types)]
2#![allow(dead_code)]
3#![allow(missing_copy_implementations)]
4
5use crate::cassandra::data_type::ConstDataType;
6use crate::cassandra::error::*;
7use crate::cassandra::iterator::LendingIterator;
8use crate::cassandra::row::Row;
9use crate::cassandra::util::{Protected, ProtectedInner};
10use crate::cassandra::value::ValueType;
11
12use crate::cassandra_sys::cass_false;
13use crate::cassandra_sys::cass_iterator_free;
14use crate::cassandra_sys::cass_iterator_from_result;
15use crate::cassandra_sys::cass_iterator_get_row;
16use crate::cassandra_sys::cass_iterator_next;
17use crate::cassandra_sys::cass_result_column_count;
18use crate::cassandra_sys::cass_result_column_data_type;
19use crate::cassandra_sys::cass_result_column_name;
20use crate::cassandra_sys::cass_result_column_type;
21use crate::cassandra_sys::cass_result_first_row;
22use crate::cassandra_sys::cass_result_free;
23use crate::cassandra_sys::cass_result_has_more_pages;
24use crate::cassandra_sys::cass_result_paging_state_token;
25use crate::cassandra_sys::cass_result_row_count;
26use crate::cassandra_sys::cass_true;
27use crate::cassandra_sys::CassIterator as _CassIterator;
28use crate::cassandra_sys::CassResult as _CassResult;
29
30use std::fmt;
31use std::fmt::Debug;
32use std::fmt::Display;
33use std::fmt::Formatter;
34use std::marker::PhantomData;
35
36use std::slice;
37use std::str;
38
39pub struct CassResult(*const _CassResult);
43unsafe impl Sync for CassResult {}
44unsafe impl Send for CassResult {}
45
46impl ProtectedInner<*const _CassResult> for CassResult {
47 fn inner(&self) -> *const _CassResult {
48 self.0
49 }
50}
51
52impl Protected<*const _CassResult> for CassResult {
53 fn build(inner: *const _CassResult) -> Self {
54 if inner.is_null() {
55 panic!("Unexpected null pointer")
56 };
57 CassResult(inner)
58 }
59}
60
61impl Debug for CassResult {
62 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
63 writeln!(f, "Result row count: {:?}", self.row_count())?;
64 let mut iter = self.iter();
65 while let Some(row) = iter.next() {
66 writeln!(f, "{:?}", row)?;
67 }
68 Ok(())
69 }
70}
71
72impl Display for CassResult {
73 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
74 writeln!(f, "Result row count: {}", self.row_count())?;
75 let mut iter = self.iter();
76 while let Some(row) = iter.next() {
77 writeln!(f, "{}", row)?;
78 }
79 Ok(())
80 }
81}
82
83impl Drop for CassResult {
84 fn drop(&mut self) {
85 unsafe { cass_result_free(self.0) }
86 }
87}
88
89impl CassResult {
90 pub fn row_count(&self) -> u64 {
92 unsafe { cass_result_row_count(self.0) as u64 }
93 }
94
95 pub fn column_count(&self) -> u64 {
97 unsafe { cass_result_column_count(self.0) as u64 }
98 }
99
100 pub fn column_name(&self, index: usize) -> Result<&str> {
102 let mut name = std::ptr::null();
103 let mut name_length = 0;
104 unsafe {
105 cass_result_column_name(self.0, index, &mut name, &mut name_length)
106 .to_result(())
107 .and_then(|_| {
108 let slice = slice::from_raw_parts(name as *const u8, name_length);
109 Ok(str::from_utf8(slice)?)
110 })
111 }
112 }
113
114 pub fn column_type(&self, index: usize) -> ValueType {
116 unsafe { ValueType::build(cass_result_column_type(self.0, index)) }
117 }
118
119 pub fn column_data_type(&self, index: usize) -> ConstDataType {
121 unsafe { ConstDataType::build(cass_result_column_data_type(self.0, index)) }
123 }
124
125 pub fn first_row(&self) -> Option<Row> {
127 unsafe {
128 match self.row_count() {
129 0 => None,
130 _ => Some(Row::build(cass_result_first_row(self.0))),
131 }
132 }
133 }
134
135 pub fn has_more_pages(&self) -> bool {
137 unsafe { cass_result_has_more_pages(self.0) == cass_true }
138 }
139
140 pub fn paging_state_token(&self) -> Result<Option<Vec<u8>>> {
150 if !self.has_more_pages() {
151 return Ok(None);
152 }
153
154 let mut token_ptr = std::ptr::null();
155 let mut token_length = 0;
156 unsafe {
157 cass_result_paging_state_token(self.0, &mut token_ptr, &mut token_length)
158 .to_result(())
159 .map(|_| Some(slice::from_raw_parts(token_ptr as *const u8, token_length).to_vec()))
160 }
161 }
162
163 pub fn iter(&self) -> ResultIterator {
166 unsafe {
167 ResultIterator(
168 cass_iterator_from_result(self.0),
169 cass_result_row_count(self.0),
170 PhantomData,
171 )
172 }
173 }
174}
175
176#[derive(Debug)]
197pub struct ResultIterator<'a>(*mut _CassIterator, usize, PhantomData<&'a _CassResult>);
198
199unsafe impl Send for ResultIterator<'_> {}
202unsafe impl Sync for ResultIterator<'_> {}
203
204impl<'a> Drop for ResultIterator<'a> {
205 fn drop(&mut self) {
206 unsafe { cass_iterator_free(self.0) }
207 }
208}
209
210impl LendingIterator for ResultIterator<'_> {
211 type Item<'a> = Row<'a> where Self: 'a;
212
213 fn next(&mut self) -> Option<<Self as LendingIterator>::Item<'_>> {
214 unsafe {
215 match cass_iterator_next(self.0) {
216 cass_false => None,
217 cass_true => Some(self.get_row()),
218 }
219 }
220 }
221
222 fn size_hint(&self) -> (usize, Option<usize>) {
223 (0, Some(self.1))
224 }
225}
226
227impl ResultIterator<'_> {
228 pub fn get_row(&self) -> Row {
230 unsafe { Row::build(cass_iterator_get_row(self.0)) }
231 }
232}