1use crate::error;
12use crate::from_raw_fdb_slice;
13use crate::future::FdbFutureHandle;
14use crate::{FdbError, FdbResult};
15use foundationdb_sys as fdb_sys;
16use std::fmt;
17use std::ops::Deref;
18
19pub struct FdbKeys {
21 _f: FdbFutureHandle,
22 keys: *const FdbKey,
23 len: i32,
24}
25unsafe impl Sync for FdbKeys {}
26unsafe impl Send for FdbKeys {}
27
28impl TryFrom<FdbFutureHandle> for FdbKeys {
29 type Error = FdbError;
30
31 fn try_from(f: FdbFutureHandle) -> FdbResult<Self> {
32 let mut keys = std::ptr::null();
33 let mut len = 0;
34
35 error::eval(unsafe { fdb_sys::fdb_future_get_key_array(f.as_ptr(), &mut keys, &mut len) })?;
36
37 Ok(FdbKeys {
38 _f: f,
39 keys: keys as *const FdbKey,
40 len,
41 })
42 }
43}
44
45impl Deref for FdbKeys {
46 type Target = [FdbKey];
47 fn deref(&self) -> &Self::Target {
48 assert_eq_size!(FdbKey, fdb_sys::FDBKey);
49 assert_eq_align!(FdbKey, u8);
50 from_raw_fdb_slice(self.keys, self.len as usize)
51 }
52}
53
54impl AsRef<[FdbKey]> for FdbKeys {
55 fn as_ref(&self) -> &[FdbKey] {
56 self.deref()
57 }
58}
59
60impl<'a> IntoIterator for &'a FdbKeys {
61 type Item = &'a FdbKey;
62 type IntoIter = std::slice::Iter<'a, FdbKey>;
63
64 fn into_iter(self) -> Self::IntoIter {
65 self.deref().iter()
66 }
67}
68
69pub struct FdbKeysIter {
71 f: std::rc::Rc<FdbFutureHandle>,
72 keys: *const FdbKey,
73 len: i32,
74 pos: i32,
75}
76
77impl Iterator for FdbKeysIter {
78 type Item = FdbRowKey;
79 fn next(&mut self) -> Option<Self::Item> {
80 #[allow(clippy::iter_nth_zero)]
81 self.nth(0)
82 }
83
84 fn size_hint(&self) -> (usize, Option<usize>) {
85 let rem = (self.len - self.pos) as usize;
86 (rem, Some(rem))
87 }
88
89 fn nth(&mut self, n: usize) -> Option<Self::Item> {
90 let pos = (self.pos as usize).checked_add(n);
91 match pos {
92 Some(pos) if pos < self.len as usize => {
93 let row_key = unsafe { self.keys.add(pos) };
95 self.pos = pos as i32 + 1;
96
97 Some(FdbRowKey {
98 _f: self.f.clone(),
99 row_key,
100 })
101 }
102 _ => {
103 self.pos = self.len;
104 None
105 }
106 }
107 }
108}
109
110impl IntoIterator for FdbKeys {
111 type Item = FdbRowKey;
112 type IntoIter = FdbKeysIter;
113
114 fn into_iter(self) -> Self::IntoIter {
115 FdbKeysIter {
116 f: std::rc::Rc::new(self._f),
117 keys: self.keys,
118 len: self.len,
119 pos: 0,
120 }
121 }
122}
123pub struct FdbRowKey {
128 _f: std::rc::Rc<FdbFutureHandle>,
129 row_key: *const FdbKey,
130}
131
132impl Deref for FdbRowKey {
133 type Target = FdbKey;
134 fn deref(&self) -> &Self::Target {
135 assert_eq_size!(FdbKey, fdb_sys::FDBKey);
136 assert_eq_align!(FdbKey, u8);
137 unsafe { &*(self.row_key) }
138 }
139}
140impl AsRef<FdbKey> for FdbRowKey {
141 fn as_ref(&self) -> &FdbKey {
142 self.deref()
143 }
144}
145impl PartialEq for FdbRowKey {
146 fn eq(&self, other: &Self) -> bool {
147 self.deref() == other.deref()
148 }
149}
150
151impl Eq for FdbRowKey {}
152impl fmt::Debug for FdbRowKey {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 self.deref().fmt(f)
155 }
156}
157
158#[repr(packed)]
159pub struct FdbKey(fdb_sys::FDBKey);
161
162impl FdbKey {
163 pub fn key(&self) -> &[u8] {
165 from_raw_fdb_slice(self.0.key, self.0.key_length as usize)
166 }
167}
168
169impl PartialEq for FdbKey {
170 fn eq(&self, other: &Self) -> bool {
171 self.key() == other.key()
172 }
173}
174
175impl Eq for FdbKey {}
176
177impl fmt::Debug for FdbKey {
178 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179 write!(f, "({:?})", crate::tuple::Bytes::from(self.key()),)
180 }
181}