1use std::borrow::Cow;
2use std::io::{ErrorKind, Write};
3
4use ordered_varint::Variable;
5
6use crate::key::{
7 ByteSource, CompositeKeyError, CompositeKind, Key, KeyEncoding, KeyVisitor, NextValueError,
8};
9
10#[deprecated = "use `CompositeKeyEncoder` instead. This function does not properly sort variable length encoded fields. See #240."]
30pub fn encode_composite_field<'k, K: Key<'k>, T: KeyEncoding<K>, Bytes: Write>(
31 value: &'k T,
32 bytes: &mut Bytes,
33) -> Result<(), CompositeKeyError> {
34 let t2 = T::as_ord_bytes(value).map_err(CompositeKeyError::new)?;
35 if T::LENGTH.is_none() {
36 (t2.len() as u64)
37 .encode_variable(&mut *bytes)
38 .map_err(CompositeKeyError::new)?;
39 }
40 bytes.write_all(&t2)?;
41 Ok(())
42}
43
44#[deprecated = "use `CompositeKeyDecoder` instead. This function does not properly sort variable length encoded fields. See #240."]
65pub fn decode_composite_field<'a, 'k, T: Key<'k>>(
66 mut bytes: &'a [u8],
67) -> Result<(T, &'a [u8]), CompositeKeyError> {
68 let length = if let Some(length) = T::LENGTH {
69 length
70 } else {
71 usize::try_from(u64::decode_variable(&mut bytes)?)?
72 };
73
74 let (t2, remaining) = bytes.split_at(length);
75 Ok((
76 T::from_ord_bytes(ByteSource::Ephemeral(t2)).map_err(CompositeKeyError::new)?,
77 remaining,
78 ))
79}
80
81#[derive(Debug, Clone)]
87#[deprecated = "This type preserves a version of tuple encoding for backwards compatibility. It it is known to have improper key ordering. See https://github.com/khonsulabs/bonsaidb/issues/240."]
88pub struct TupleEncodingV1<T>(pub T);
89
90macro_rules! count_args {
91 () => (0usize);
92 ( $arg:tt $($remaining:tt)* ) => (1usize + count_args!($($remaining)*));
93}
94
95macro_rules! impl_key_for_tuple_v1 {
96 ($(($index:tt, $varname:ident, $generic:ident)),+) => {
97 #[allow(deprecated)]
98 impl<'k, $($generic),+> Key<'k> for TupleEncodingV1<($($generic),+,)>
99 where
100 $($generic: for<'ke> Key<'ke>),+
101 {
102 const CAN_OWN_BYTES: bool = false;
103 fn from_ord_bytes<'e>(bytes: ByteSource<'k, 'e>) -> Result<Self, Self::Error> {
104 let bytes = bytes.as_ref();
105 $(let ($varname, bytes) = decode_composite_field::<$generic>(bytes)?;)+
106
107 if bytes.is_empty() {
108 Ok(Self(($($varname),+,)))
109 } else {
110 Err(CompositeKeyError::new(std::io::Error::from(
111 ErrorKind::InvalidData,
112 )))
113 }
114 }
115 }
116
117 #[allow(deprecated)]
118 impl<$($generic),+> KeyEncoding<Self> for TupleEncodingV1<($($generic),+,)>
119 where
120 $($generic: for<'k> Key<'k>),+
121 {
122 type Error = CompositeKeyError;
123
124 const LENGTH: Option<usize> = match ($($generic::LENGTH),+,) {
125 ($(Some($varname)),+,) => Some($($varname +)+ 0),
126 _ => None,
127 };
128
129 fn describe<Visitor>(visitor: &mut Visitor)
130 where
131 Visitor: KeyVisitor,
132 {
133 visitor.visit_composite(CompositeKind::Tuple, count_args!($($generic)+));
134 $($generic::describe(visitor);)+
135 }
136
137 fn as_ord_bytes(&self) -> Result<Cow<'_, [u8]>, Self::Error> {
138 let mut bytes = Vec::new();
139
140 $(encode_composite_field(&self.0.$index, &mut bytes)?;)+
141
142 Ok(Cow::Owned(bytes))
143 }
144 }
145 };
146}
147
148impl_key_for_tuple_v1!((0, t1, T1));
149impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2));
150impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2), (2, t3, T3));
151impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2), (2, t3, T3), (3, t4, T4));
152impl_key_for_tuple_v1!(
153 (0, t1, T1),
154 (1, t2, T2),
155 (2, t3, T3),
156 (3, t4, T4),
157 (4, t5, T5)
158);
159impl_key_for_tuple_v1!(
160 (0, t1, T1),
161 (1, t2, T2),
162 (2, t3, T3),
163 (3, t4, T4),
164 (4, t5, T5),
165 (5, t6, T6)
166);
167impl_key_for_tuple_v1!(
168 (0, t1, T1),
169 (1, t2, T2),
170 (2, t3, T3),
171 (3, t4, T4),
172 (4, t5, T5),
173 (5, t6, T6),
174 (6, t7, T7)
175);
176impl_key_for_tuple_v1!(
177 (0, t1, T1),
178 (1, t2, T2),
179 (2, t3, T3),
180 (3, t4, T4),
181 (4, t5, T5),
182 (5, t6, T6),
183 (6, t7, T7),
184 (7, t8, T8)
185);
186
187#[derive(Clone, Debug, Copy, Eq, PartialEq)]
191#[deprecated = "this type should not be used in new code and should only be used in transitionary code."]
192#[allow(deprecated)]
193pub struct OptionKeyV1<T>(pub Option<T>);
194
195#[allow(deprecated)]
196impl<'k, T> Key<'k> for OptionKeyV1<T>
197where
198 T: Key<'k>,
199 Self: KeyEncoding<Self, Error = <T as KeyEncoding<T>>::Error>,
200{
201 const CAN_OWN_BYTES: bool = false;
202
203 fn from_ord_bytes<'b>(bytes: ByteSource<'k, 'b>) -> Result<Self, Self::Error> {
204 if bytes.as_ref().is_empty() {
205 Ok(Self(None))
206 } else {
207 Ok(Self(Some(T::from_ord_bytes(bytes)?)))
208 }
209 }
210
211 fn first_value() -> Result<Self, NextValueError> {
212 Ok(Self(Some(T::first_value()?)))
213 }
214
215 fn next_value(&self) -> Result<Self, NextValueError> {
216 self.0.as_ref().map(T::next_value).transpose().map(Self)
217 }
218}
219
220#[allow(deprecated)]
221impl<K, T> KeyEncoding<OptionKeyV1<K>> for OptionKeyV1<T>
222where
223 T: KeyEncoding<K>,
224 K: for<'k> Key<'k>,
225{
226 type Error = T::Error;
227
228 const LENGTH: Option<usize> = T::LENGTH;
229
230 fn describe<Visitor>(visitor: &mut Visitor)
231 where
232 Visitor: KeyVisitor,
233 {
234 visitor.visit_composite(CompositeKind::Option, 1);
235 T::describe(visitor);
236 }
237
238 fn as_ord_bytes(&self) -> Result<Cow<'_, [u8]>, Self::Error> {
242 if let Some(contents) = &self.0 {
243 let contents = contents.as_ord_bytes()?;
244 assert!(!contents.is_empty());
245 Ok(contents)
246 } else {
247 Ok(Cow::default())
248 }
249 }
250}