1use crate::{
2 cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW},
3 transaction::{DbTx, DbTxMut},
4 DatabaseError,
5};
6
7use serde::{Deserialize, Serialize};
8use std::fmt::Debug;
9
10pub trait Compress: Send + Sync + Sized + Debug {
12 type Compressed: bytes::BufMut
14 + AsRef<[u8]>
15 + AsMut<[u8]>
16 + Into<Vec<u8>>
17 + Default
18 + Send
19 + Sync
20 + Debug;
21
22 fn uncompressable_ref(&self) -> Option<&[u8]> {
24 None
25 }
26
27 fn compress(self) -> Self::Compressed {
29 let mut buf = Self::Compressed::default();
30 self.compress_to_buf(&mut buf);
31 buf
32 }
33
34 fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B);
36}
37
38pub trait Decompress: Send + Sync + Sized + Debug {
40 fn decompress(value: &[u8]) -> Result<Self, DatabaseError>;
42
43 fn decompress_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
45 Self::decompress(&value)
46 }
47}
48
49pub trait IntoVec: AsRef<[u8]> {
54 fn into_vec(self) -> Vec<u8>;
56}
57
58impl IntoVec for Vec<u8> {
59 #[inline]
60 fn into_vec(self) -> Vec<u8> {
61 self
62 }
63}
64
65impl<const N: usize> IntoVec for [u8; N] {
66 #[inline]
67 fn into_vec(self) -> Vec<u8> {
68 self.to_vec()
69 }
70}
71
72impl<const N: usize> IntoVec for arrayvec::ArrayVec<u8, N> {
73 #[inline]
74 fn into_vec(self) -> Vec<u8> {
75 self.to_vec()
76 }
77}
78
79pub trait Encode: Send + Sync + Sized + Debug {
81 type Encoded: AsRef<[u8]> + IntoVec + Send + Sync + Ord + Debug;
83
84 fn encode(self) -> Self::Encoded;
86}
87
88pub trait Decode: Send + Sync + Sized + Debug {
90 fn decode(value: &[u8]) -> Result<Self, DatabaseError>;
92
93 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
95 Self::decode(&value)
96 }
97}
98
99pub trait Key: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
101
102impl<T> Key for T where T: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
103
104pub trait Value: Compress + Decompress + Serialize {}
106
107impl<T> Value for T where T: Compress + Decompress + Serialize {}
108
109pub trait Table: Send + Sync + Debug + 'static {
118 const NAME: &'static str;
120
121 const DUPSORT: bool;
123
124 type Key: Key;
128
129 type Value: Value;
131}
132
133pub trait TableInfo: Send + Sync + Debug + 'static {
135 fn name(&self) -> &'static str;
137
138 fn is_dupsort(&self) -> bool;
140}
141
142pub type TableRow<T> = (<T as Table>::Key, <T as Table>::Value);
144
145pub trait DupSort: Table {
149 type SubKey: Key;
155}
156
157pub trait TableImporter: DbTxMut {
159 fn import_table<T: Table, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
161 let mut destination_cursor = self.cursor_write::<T>()?;
162
163 for kv in source_tx.cursor_read::<T>()?.walk(None)? {
164 let (k, v) = kv?;
165 destination_cursor.append(k, &v)?;
166 }
167
168 Ok(())
169 }
170
171 fn import_table_with_range<T: Table, R: DbTx>(
176 &self,
177 source_tx: &R,
178 from: Option<<T as Table>::Key>,
179 to: <T as Table>::Key,
180 ) -> Result<(), DatabaseError>
181 where
182 T::Key: Default,
183 {
184 let mut destination_cursor = self.cursor_write::<T>()?;
185 let mut source_cursor = source_tx.cursor_read::<T>()?;
186
187 let source_range = match from {
188 Some(from) => source_cursor.walk_range(from..=to),
189 None => source_cursor.walk_range(..=to),
190 };
191 for row in source_range? {
192 let (key, value) = row?;
193 destination_cursor.append(key, &value)?;
194 }
195
196 Ok(())
197 }
198
199 fn import_dupsort<T: DupSort, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
201 let mut destination_cursor = self.cursor_dup_write::<T>()?;
202 let mut cursor = source_tx.cursor_dup_read::<T>()?;
203
204 while let Some((k, _)) = cursor.next_no_dup()? {
205 for kv in cursor.walk_dup(Some(k), None)? {
206 let (k, v) = kv?;
207 destination_cursor.append_dup(k, v)?;
208 }
209 }
210
211 Ok(())
212 }
213}