1
use std::borrow::Cow;
2
use std::io::{ErrorKind, Write};
3

            
4
use ordered_varint::Variable;
5

            
6
use 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."]
30
pub 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."]
65
pub 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."]
88
pub struct TupleEncodingV1<T>(pub T);
89

            
90
macro_rules! count_args {
91
    () => (0usize);
92
    ( $arg:tt $($remaining:tt)* ) => (1usize + count_args!($($remaining)*));
93
}
94

            
95
macro_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

            
148
impl_key_for_tuple_v1!((0, t1, T1));
149
impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2));
150
impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2), (2, t3, T3));
151
impl_key_for_tuple_v1!((0, t1, T1), (1, t2, T2), (2, t3, T3), (3, t4, T4));
152
impl_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
);
159
impl_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
);
167
impl_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
);
176
impl_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)]
193
pub struct OptionKeyV1<T>(pub Option<T>);
194

            
195
#[allow(deprecated)]
196
impl<'k, T> Key<'k> for OptionKeyV1<T>
197
where
198
    T: Key<'k>,
199
    Self: KeyEncoding<Self, Error = <T as KeyEncoding<T>>::Error>,
200
{
201
    const CAN_OWN_BYTES: bool = false;
202

            
203
2
    fn from_ord_bytes<'b>(bytes: ByteSource<'k, 'b>) -> Result<Self, Self::Error> {
204
2
        if bytes.as_ref().is_empty() {
205
1
            Ok(Self(None))
206
        } else {
207
1
            Ok(Self(Some(T::from_ord_bytes(bytes)?)))
208
        }
209
2
    }
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)]
221
impl<K, T> KeyEncoding<OptionKeyV1<K>> for OptionKeyV1<T>
222
where
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
2
    fn as_ord_bytes(&self) -> Result<Cow<'_, [u8]>, Self::Error> {
242
2
        if let Some(contents) = &self.0 {
243
1
            let contents = contents.as_ord_bytes()?;
244
1
            assert!(!contents.is_empty());
245
1
            Ok(contents)
246
        } else {
247
1
            Ok(Cow::default())
248
        }
249
2
    }
250
}