discord_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::row::Row;
8use crate::cassandra::util::{Protected, ProtectedInner};
9use crate::cassandra::value::ValueType;
10
11use crate::cassandra_sys::cass_false;
12use crate::cassandra_sys::cass_iterator_free;
13use crate::cassandra_sys::cass_iterator_from_result;
14use crate::cassandra_sys::cass_iterator_get_row;
15use crate::cassandra_sys::cass_iterator_next;
16use crate::cassandra_sys::cass_result_column_count;
17use crate::cassandra_sys::cass_result_column_data_type;
18use crate::cassandra_sys::cass_result_column_name;
19use crate::cassandra_sys::cass_result_column_type;
20use crate::cassandra_sys::cass_result_first_row;
21use crate::cassandra_sys::cass_result_free;
22use crate::cassandra_sys::cass_result_has_more_pages;
23use crate::cassandra_sys::cass_result_paging_state_token;
24use crate::cassandra_sys::cass_result_row_count;
25use crate::cassandra_sys::cass_true;
26use crate::cassandra_sys::CassIterator as _CassIterator;
27use crate::cassandra_sys::CassResult as _CassResult;
28
29use std::ffi::CString;
30use std::fmt;
31use std::fmt::Debug;
32use std::fmt::Display;
33use std::fmt::Formatter;
34use std::marker::PhantomData;
35use std::mem;
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 write!(f, "Result row count: {:?}\n", self.row_count())?;
64 for row in self.iter() {
65 write!(f, "{:?}\n", row)?;
66 }
67 Ok(())
68 }
69}
70
71impl Display for CassResult {
72 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
73 write!(f, "Result row count: {}\n", self.row_count())?;
74 for row in self.iter() {
75 write!(f, "{}\n", row)?;
76 }
77 Ok(())
78 }
79}
80
81impl Drop for CassResult {
82 fn drop(&mut self) {
83 unsafe { cass_result_free(self.0) }
84 }
85}
86
87impl CassResult {
88 pub fn row_count(&self) -> u64 {
90 unsafe { cass_result_row_count(self.0) as u64 }
91 }
92
93 pub fn column_count(&self) -> u64 {
95 unsafe { cass_result_column_count(self.0) as u64 }
96 }
97
98 pub fn column_name(&self, index: usize) -> Result<&str> {
100 unsafe {
101 let mut name = mem::zeroed();
102 let mut name_length = mem::zeroed();
103 cass_result_column_name(self.0, index, &mut name, &mut name_length)
104 .to_result(())
105 .and_then(|_| {
106 let slice = slice::from_raw_parts(name as *const u8, name_length as usize);
107 Ok(str::from_utf8(slice)?)
108 })
109 }
110 }
111
112 pub fn column_type(&self, index: usize) -> ValueType {
114 unsafe { ValueType::build(cass_result_column_type(self.0, index)) }
115 }
116
117 pub fn column_data_type(&self, index: usize) -> ConstDataType {
119 unsafe { ConstDataType::build(cass_result_column_data_type(self.0, index)) }
121 }
122
123 pub fn first_row(&self) -> Option<Row> {
125 unsafe {
126 match self.row_count() {
127 0 => None,
128 _ => Some(Row::build(cass_result_first_row(self.0))),
129 }
130 }
131 }
132
133 pub fn has_more_pages(&self) -> bool {
135 unsafe { cass_result_has_more_pages(self.0) == cass_true }
136 }
137
138 pub fn paging_state_token(&self) -> Result<Option<Vec<u8>>> {
148 if !self.has_more_pages() {
149 return Ok(None);
150 }
151
152 unsafe {
153 let mut token_ptr = mem::zeroed();
154 let mut token_length = mem::zeroed();
155 cass_result_paging_state_token(
156 self.0,
157 &mut token_ptr,
158 &mut token_length,
159 )
160 .to_result(())
161 .map(|_| {
162 Some(
163 slice::from_raw_parts(token_ptr as *const u8, token_length as usize)
164 .to_vec(),
165 )
166 })
167 }
168 }
169
170 pub fn iter(&self) -> ResultIterator {
173 unsafe {
174 ResultIterator(
175 cass_iterator_from_result(self.0),
176 cass_result_row_count(self.0),
177 PhantomData,
178 )
179 }
180 }
181}
182
183#[derive(Debug)]
186pub struct ResultIterator<'a>(pub *mut _CassIterator, usize, PhantomData<&'a CassResult>);
187
188unsafe impl<'a> Send for ResultIterator<'a> {}
191
192impl<'a> Drop for ResultIterator<'a> {
193 fn drop(&mut self) {
194 unsafe { cass_iterator_free(self.0) }
195 }
196}
197
198impl<'a> Iterator for ResultIterator<'a> {
199 type Item = Row<'a>;
200 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
201 unsafe {
202 match cass_iterator_next(self.0) {
203 cass_false => None,
204 cass_true => Some(self.get_row()),
205 }
206 }
207 }
208
209 fn size_hint(&self) -> (usize, Option<usize>) {
210 (0, Some(self.1))
211 }
212}
213
214impl<'a> ResultIterator<'a> {
215 pub fn get_row(&mut self) -> Row<'a> {
217 unsafe { Row::build(cass_iterator_get_row(self.0)) }
218 }
219}
220
221impl<'a> IntoIterator for &'a CassResult {
222 type Item = Row<'a>;
223 type IntoIter = ResultIterator<'a>;
224
225 fn into_iter(self) -> Self::IntoIter {
226 self.iter()
227 }
228}