use crate::error::{check_result, Error, Result};
use crate::ffi;
use std::ptr;
pub struct Iterator {
iter: *mut ffi::tidesdb_iter_t,
}
unsafe impl Send for Iterator {}
impl Iterator {
pub(crate) fn new(iter: *mut ffi::tidesdb_iter_t) -> Self {
Iterator { iter }
}
pub fn seek_to_first(&mut self) -> Result<()> {
let result = unsafe { ffi::tidesdb_iter_seek_to_first(self.iter) };
check_result(result, "failed to seek to first")
}
pub fn seek_to_last(&mut self) -> Result<()> {
let result = unsafe { ffi::tidesdb_iter_seek_to_last(self.iter) };
check_result(result, "failed to seek to last")
}
pub fn seek(&mut self, key: &[u8]) -> Result<()> {
let key_ptr = if key.is_empty() {
ptr::null()
} else {
key.as_ptr()
};
let result = unsafe { ffi::tidesdb_iter_seek(self.iter, key_ptr, key.len()) };
check_result(result, "failed to seek")
}
pub fn seek_for_prev(&mut self, key: &[u8]) -> Result<()> {
let key_ptr = if key.is_empty() {
ptr::null()
} else {
key.as_ptr()
};
let result = unsafe { ffi::tidesdb_iter_seek_for_prev(self.iter, key_ptr, key.len()) };
check_result(result, "failed to seek for prev")
}
pub fn is_valid(&self) -> bool {
unsafe { ffi::tidesdb_iter_valid(self.iter) != 0 }
}
pub fn next(&mut self) -> Result<()> {
let result = unsafe { ffi::tidesdb_iter_next(self.iter) };
if result == ffi::TDB_ERR_NOT_FOUND || result == ffi::TDB_SUCCESS {
Ok(())
} else {
Err(crate::error::Error::from_code(result, "failed to move to next"))
}
}
pub fn prev(&mut self) -> Result<()> {
let result = unsafe { ffi::tidesdb_iter_prev(self.iter) };
if result == ffi::TDB_ERR_NOT_FOUND || result == ffi::TDB_SUCCESS {
Ok(())
} else {
Err(crate::error::Error::from_code(result, "failed to move to prev"))
}
}
pub fn key(&self) -> Result<Vec<u8>> {
let mut key_ptr: *mut u8 = ptr::null_mut();
let mut key_len: usize = 0;
let result = unsafe { ffi::tidesdb_iter_key(self.iter, &mut key_ptr, &mut key_len) };
check_result(result, "failed to get key")?;
if key_ptr.is_null() {
return Err(Error::NullPointer("key"));
}
let key = unsafe {
let slice = std::slice::from_raw_parts(key_ptr, key_len);
slice.to_vec()
};
Ok(key)
}
pub fn key_value(&self) -> Result<(Vec<u8>, Vec<u8>)> {
let mut key_ptr: *mut u8 = ptr::null_mut();
let mut key_len: usize = 0;
let mut value_ptr: *mut u8 = ptr::null_mut();
let mut value_len: usize = 0;
let result = unsafe {
ffi::tidesdb_iter_key_value(
self.iter,
&mut key_ptr,
&mut key_len,
&mut value_ptr,
&mut value_len,
)
};
check_result(result, "failed to get key-value")?;
if key_ptr.is_null() {
return Err(Error::NullPointer("key"));
}
if value_ptr.is_null() {
return Err(Error::NullPointer("value"));
}
let key = unsafe { std::slice::from_raw_parts(key_ptr, key_len) }.to_vec();
let value = unsafe { std::slice::from_raw_parts(value_ptr, value_len) }.to_vec();
Ok((key, value))
}
pub fn value(&self) -> Result<Vec<u8>> {
let mut value_ptr: *mut u8 = ptr::null_mut();
let mut value_len: usize = 0;
let result = unsafe { ffi::tidesdb_iter_value(self.iter, &mut value_ptr, &mut value_len) };
check_result(result, "failed to get value")?;
if value_ptr.is_null() {
return Err(Error::NullPointer("value"));
}
let value = unsafe {
let slice = std::slice::from_raw_parts(value_ptr, value_len);
slice.to_vec()
};
Ok(value)
}
}
impl Drop for Iterator {
fn drop(&mut self) {
if !self.iter.is_null() {
unsafe {
ffi::tidesdb_iter_free(self.iter);
}
self.iter = ptr::null_mut();
}
}
}