bonsaidb_core/key/
deprecated.rs

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/// Encodes a value using the `Key` trait in such a way that multiple values can
11/// still be ordered at the byte level when chained together.
12///
13/// ```rust
14/// # #![allow(deprecated)]
15/// # use bonsaidb_core::key::{encode_composite_field, decode_composite_field};
16///
17/// let value1 = String::from("hello");
18/// let value2 = 42_u32;
19/// let mut key_bytes = Vec::new();
20/// encode_composite_field(&value1, &mut key_bytes).unwrap();
21/// encode_composite_field(&value2, &mut key_bytes).unwrap();
22///
23/// let (decoded_string, remaining_bytes) = decode_composite_field::<String>(&key_bytes).unwrap();
24/// assert_eq!(decoded_string, value1);
25/// let (decoded_u32, remaining_bytes) = decode_composite_field::<u32>(&remaining_bytes).unwrap();
26/// assert_eq!(decoded_u32, value2);
27/// assert!(remaining_bytes.is_empty());
28/// ```
29#[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/// Decodes a value previously encoded using [`encode_composite_field()`].
45/// The result is a tuple with the first element being the decoded value, and
46/// the second element is the remainig byte slice.
47///
48/// ```rust
49/// # #![allow(deprecated)]
50/// # use bonsaidb_core::key::{encode_composite_field, decode_composite_field};
51///
52/// let value1 = String::from("hello");
53/// let value2 = 42_u32;
54/// let mut key_bytes = Vec::new();
55/// encode_composite_field(&value1, &mut key_bytes).unwrap();
56/// encode_composite_field(&value2, &mut key_bytes).unwrap();
57///
58/// let (decoded_string, remaining_bytes) = decode_composite_field::<String>(&key_bytes).unwrap();
59/// assert_eq!(decoded_string, value1);
60/// let (decoded_u32, remaining_bytes) = decode_composite_field::<u32>(&remaining_bytes).unwrap();
61/// assert_eq!(decoded_u32, value2);
62/// assert!(remaining_bytes.is_empty());
63/// ```
64#[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/// This type enables wrapping a tuple to preserve the behavior of the initial
82/// implementation of tuple key encoding. This type should not be used in new
83/// code and should only be used to preserve backwards compatibility. See
84/// <https://github.com/khonsulabs/bonsaidb/issues/240> for more information
85/// about why this implementation should be avoided.
86#[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/// A type that preserves the original implementation of [`Key`] for
188/// `Option<T>`. This should not be used in new code and will be removed in a
189/// future version.
190#[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    /// # Panics
239    ///
240    /// Panics if `T::into_big_endian_bytes` returns an empty `IVec`
241    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}