1
use std::{
2
    borrow::Cow, convert::Infallible, io::ErrorKind, num::TryFromIntError, string::FromUtf8Error,
3
};
4

            
5
use arc_bytes::{
6
    serde::{Bytes, CowBytes},
7
    ArcBytes,
8
};
9
use num_traits::{FromPrimitive, ToPrimitive};
10
use ordered_varint::{Signed, Unsigned, Variable};
11
use serde::{Deserialize, Serialize};
12

            
13
use crate::AnyError;
14

            
15
/// A trait that enables a type to convert itself into a `memcmp`-compatible
16
/// sequence of bytes.
17
pub trait Key<'k>: Clone + std::fmt::Debug + Send + Sync {
18
    /// The error type that can be produced by either serialization or
19
    /// deserialization.
20
    type Error: AnyError;
21

            
22
    /// The size of the key, if constant. If this type doesn't produce the same
23
    /// number of bytes for each value, this should be `None`.
24
    const LENGTH: Option<usize>;
25

            
26
    /// Convert `self` into a `Cow<[u8]>` containing bytes that are able to be
27
    /// compared via `memcmp` in a way that is comptaible with its own Ord
28
    /// implementation.
29
    fn as_ord_bytes(&'k self) -> Result<Cow<'k, [u8]>, Self::Error>;
30

            
31
    /// Deserialize a sequence of bytes previously encoded with
32
    /// [`Self::as_ord_bytes`].
33
    fn from_ord_bytes(bytes: &'k [u8]) -> Result<Self, Self::Error>;
34

            
35
    /// Return the first value in sequence for this type. Not all types
36
    /// implement this.
37
    fn first_value() -> Result<Self, NextValueError> {
38
        Err(NextValueError::Unsupported)
39
    }
40

            
41
    /// Return the next value in sequence for this type. Not all types implement
42
    /// this. Instead of wrapping/overflowing, None should be returned.
43
1
    fn next_value(&self) -> Result<Self, NextValueError> {
44
1
        Err(NextValueError::Unsupported)
45
1
    }
46
}
47

            
48
/// The error types for [`Key::next_value()`].
49
#[derive(Clone, thiserror::Error, Debug, Serialize, Deserialize)]
50
pub enum NextValueError {
51
    /// The key type does not support this operation.
52
    #[error("the key type does not support automatic ids")]
53
    Unsupported,
54
    /// Generating a new value would wrap the underlying value.
55
    #[error("the key type has run out of unique values")]
56
    WouldWrap,
57
}
58

            
59
impl<'k> Key<'k> for Cow<'k, [u8]> {
60
    type Error = Infallible;
61

            
62
    const LENGTH: Option<usize> = None;
63

            
64
1
    fn as_ord_bytes(&'k self) -> Result<Cow<'k, [u8]>, Self::Error> {
65
1
        Ok(self.clone())
66
1
    }
67

            
68
1
    fn from_ord_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
69
1
        Ok(Cow::Owned(bytes.to_vec()))
70
1
    }
71
}
72

            
73
impl<'a> Key<'a> for Vec<u8> {
74
    type Error = Infallible;
75

            
76
    const LENGTH: Option<usize> = None;
77

            
78
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
79
        Ok(Cow::Borrowed(self))
80
    }
81

            
82
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
83
        Ok(bytes.to_vec())
84
    }
85
}
86

            
87
impl<'a> Key<'a> for ArcBytes<'a> {
88
    type Error = Infallible;
89

            
90
    const LENGTH: Option<usize> = None;
91

            
92
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
93
        Ok(Cow::Borrowed(self))
94
    }
95

            
96
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
97
        Ok(Self::from(bytes))
98
    }
99
}
100

            
101
impl<'a> Key<'a> for CowBytes<'a> {
102
    type Error = Infallible;
103

            
104
    const LENGTH: Option<usize> = None;
105

            
106
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
107
        Ok(self.0.clone())
108
    }
109

            
110
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
111
        Ok(Self::from(bytes))
112
    }
113
}
114

            
115
impl<'a> Key<'a> for Bytes {
116
    type Error = Infallible;
117

            
118
    const LENGTH: Option<usize> = None;
119

            
120
651196
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
121
651196
        Ok(Cow::Borrowed(self))
122
651196
    }
123

            
124
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
125
        Ok(Self::from(bytes))
126
    }
127
}
128

            
129
impl<'a> Key<'a> for String {
130
    type Error = FromUtf8Error;
131

            
132
    const LENGTH: Option<usize> = None;
133

            
134
318267
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
135
318267
        Ok(Cow::Borrowed(self.as_bytes()))
136
318267
    }
137

            
138
291486
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
139
291486
        Self::from_utf8(bytes.to_vec())
140
291486
    }
141
}
142

            
143
impl<'a> Key<'a> for () {
144
    type Error = Infallible;
145

            
146
    const LENGTH: Option<usize> = Some(0);
147

            
148
53
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
149
53
        Ok(Cow::default())
150
53
    }
151

            
152
79
    fn from_ord_bytes(_: &'a [u8]) -> Result<Self, Self::Error> {
153
79
        Ok(())
154
79
    }
155
}
156

            
157
impl<'a> Key<'a> for bool {
158
    type Error = Infallible;
159

            
160
    const LENGTH: Option<usize> = Some(1);
161

            
162
2
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
163
2
        if *self {
164
1
            Ok(Cow::Borrowed(&[1_u8]))
165
        } else {
166
1
            Ok(Cow::Borrowed(&[0_u8]))
167
        }
168
2
    }
169

            
170
2
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
171
2
        if bytes.is_empty() || bytes[0] == 0 {
172
1
            Ok(false)
173
        } else {
174
1
            Ok(true)
175
        }
176
2
    }
177
}
178

            
179
macro_rules! impl_key_for_tuple {
180
    ($(($index:tt, $varname:ident, $generic:ident)),+) => {
181
        impl<'a, $($generic),+> Key<'a> for ($($generic),+)
182
        where
183
            $($generic: Key<'a>),+
184
        {
185
            type Error = CompositeKeyError;
186

            
187
            const LENGTH: Option<usize> = match ($($generic::LENGTH),+) {
188
                ($(Some($varname)),+) => Some($($varname +)+ 0),
189
                _ => None,
190
            };
191

            
192
510
            fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
193
510
                let mut bytes = Vec::new();
194
510

            
195
510
                $(encode_composite_key_field(&self.$index, &mut bytes)?;)+
196

            
197
510
                Ok(Cow::Owned(bytes))
198
510
            }
199

            
200
511
            fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
201
511
                $(let ($varname, bytes) = decode_composite_key_field::<$generic>(bytes)?;)+
202

            
203
511
                if bytes.is_empty() {
204
511
                    Ok(($($varname),+))
205
                } else {
206
                    Err(CompositeKeyError::new(std::io::Error::from(
207
                        ErrorKind::InvalidData,
208
                    )))
209
                }
210
511
            }
211
        }
212
    };
213
}
214

            
215
impl_key_for_tuple!((0, t1, T1), (1, t2, T2));
216
impl_key_for_tuple!((0, t1, T1), (1, t2, T2), (2, t3, T3));
217
impl_key_for_tuple!((0, t1, T1), (1, t2, T2), (2, t3, T3), (3, t4, T4));
218
impl_key_for_tuple!(
219
    (0, t1, T1),
220
    (1, t2, T2),
221
    (2, t3, T3),
222
    (3, t4, T4),
223
    (4, t5, T5)
224
);
225
impl_key_for_tuple!(
226
    (0, t1, T1),
227
    (1, t2, T2),
228
    (2, t3, T3),
229
    (3, t4, T4),
230
    (4, t5, T5),
231
    (5, t6, T6)
232
);
233
impl_key_for_tuple!(
234
    (0, t1, T1),
235
    (1, t2, T2),
236
    (2, t3, T3),
237
    (3, t4, T4),
238
    (4, t5, T5),
239
    (5, t6, T6),
240
    (6, t7, T7)
241
);
242
impl_key_for_tuple!(
243
    (0, t1, T1),
244
    (1, t2, T2),
245
    (2, t3, T3),
246
    (3, t4, T4),
247
    (4, t5, T5),
248
    (5, t6, T6),
249
    (6, t7, T7),
250
    (7, t8, T8)
251
);
252

            
253
3588
fn encode_composite_key_field<'a, T: Key<'a>>(
254
3588
    value: &'a T,
255
3588
    bytes: &mut Vec<u8>,
256
3588
) -> Result<(), CompositeKeyError> {
257
3588
    let t2 = T::as_ord_bytes(value).map_err(CompositeKeyError::new)?;
258
3588
    if T::LENGTH.is_none() {
259
3584
        (t2.len() as u64)
260
3584
            .encode_variable(bytes)
261
3584
            .map_err(CompositeKeyError::new)?;
262
4
    }
263
3588
    bytes.extend(t2.iter().copied());
264
3588
    Ok(())
265
3588
}
266

            
267
3590
fn decode_composite_key_field<'a, T: Key<'a>>(
268
3590
    mut bytes: &'a [u8],
269
3590
) -> Result<(T, &[u8]), CompositeKeyError> {
270
3590
    let length = if let Some(length) = T::LENGTH {
271
6
        length
272
    } else {
273
3584
        usize::try_from(u64::decode_variable(&mut bytes)?)?
274
    };
275
3590
    let (t2, remaining) = bytes.split_at(length);
276
3590
    Ok((
277
3590
        T::from_ord_bytes(t2).map_err(CompositeKeyError::new)?,
278
3590
        remaining,
279
    ))
280
3590
}
281

            
282
1
#[test]
283
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)] // couldn't figure out how to macro-ize it
284
1
fn composite_key_tests() {
285
7
    fn roundtrip<T: for<'a> Key<'a> + Ord + Eq + std::fmt::Debug>(mut cases: Vec<T>) {
286
7
        let mut encoded = {
287
7
            cases
288
7
                .iter()
289
508
                .map(|tuple| tuple.as_ord_bytes().unwrap().to_vec())
290
7
                .collect::<Vec<Vec<u8>>>()
291
7
        };
292
7
        cases.sort();
293
7
        encoded.sort();
294
7
        let decoded = encoded
295
7
            .iter()
296
508
            .map(|encoded| T::from_ord_bytes(encoded).unwrap())
297
7
            .collect::<Vec<_>>();
298
7
        assert_eq!(cases, decoded);
299
7
    }
300
1

            
301
1
    let values = [Unsigned::from(0_u8), Unsigned::from(16_u8)];
302
1
    let mut cases = Vec::new();
303
3
    for t1 in values {
304
6
        for t2 in values {
305
4
            cases.push((t1, t2));
306
4
        }
307
    }
308
1
    roundtrip(cases);
309
1

            
310
1
    let mut cases = Vec::new();
311
3
    for t1 in values {
312
6
        for t2 in values {
313
12
            for t3 in values {
314
8
                cases.push((t1, t2, t3));
315
8
            }
316
        }
317
    }
318
1
    roundtrip(cases);
319
1

            
320
1
    let mut cases = Vec::new();
321
3
    for t1 in values {
322
6
        for t2 in values {
323
12
            for t3 in values {
324
24
                for t4 in values {
325
16
                    cases.push((t1, t2, t3, t4));
326
16
                }
327
            }
328
        }
329
    }
330
1
    roundtrip(cases);
331
1

            
332
1
    let mut cases = Vec::new();
333
3
    for t1 in values {
334
6
        for t2 in values {
335
12
            for t3 in values {
336
24
                for t4 in values {
337
48
                    for t5 in values {
338
32
                        cases.push((t1, t2, t3, t4, t5));
339
32
                    }
340
                }
341
            }
342
        }
343
    }
344
1
    roundtrip(cases);
345
1

            
346
1
    let mut cases = Vec::new();
347
3
    for t1 in values {
348
6
        for t2 in values {
349
12
            for t3 in values {
350
24
                for t4 in values {
351
48
                    for t5 in values {
352
96
                        for t6 in values {
353
64
                            cases.push((t1, t2, t3, t4, t5, t6));
354
64
                        }
355
                    }
356
                }
357
            }
358
        }
359
    }
360
1
    roundtrip(cases);
361
1

            
362
1
    let mut cases = Vec::new();
363
3
    for t1 in values {
364
6
        for t2 in values {
365
12
            for t3 in values {
366
24
                for t4 in values {
367
48
                    for t5 in values {
368
96
                        for t6 in values {
369
192
                            for t7 in values {
370
128
                                cases.push((t1, t2, t3, t4, t5, t6, t7));
371
128
                            }
372
                        }
373
                    }
374
                }
375
            }
376
        }
377
    }
378
1
    roundtrip(cases);
379
1

            
380
1
    let mut cases = Vec::new();
381
3
    for t1 in values {
382
6
        for t2 in values {
383
12
            for t3 in values {
384
24
                for t4 in values {
385
48
                    for t5 in values {
386
96
                        for t6 in values {
387
192
                            for t7 in values {
388
384
                                for t8 in values {
389
256
                                    cases.push((t1, t2, t3, t4, t5, t6, t7, t8));
390
256
                                }
391
                            }
392
                        }
393
                    }
394
                }
395
            }
396
        }
397
    }
398
1
    roundtrip(cases);
399
1
}
400

            
401
/// An error occurred inside of one of the composite key fields.
402
#[derive(thiserror::Error, Debug)]
403
#[error("key error: {0}")]
404
pub struct CompositeKeyError(Box<dyn AnyError>);
405

            
406
impl CompositeKeyError {
407
    pub(crate) fn new<E: AnyError>(error: E) -> Self {
408
        Self(Box::new(error))
409
    }
410
}
411

            
412
impl From<TryFromIntError> for CompositeKeyError {
413
    fn from(err: TryFromIntError) -> Self {
414
        Self::new(err)
415
    }
416
}
417

            
418
impl From<std::io::Error> for CompositeKeyError {
419
    fn from(err: std::io::Error) -> Self {
420
        Self::new(err)
421
    }
422
}
423

            
424
impl<'a> Key<'a> for Signed {
425
    type Error = std::io::Error;
426

            
427
    const LENGTH: Option<usize> = None;
428

            
429
    fn as_ord_bytes(&self) -> Result<Cow<'a, [u8]>, Self::Error> {
430
        self.to_variable_vec().map(Cow::Owned)
431
    }
432

            
433
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
434
        Self::decode_variable(bytes)
435
    }
436

            
437
    fn first_value() -> Result<Self, NextValueError> {
438
        Ok(Self::from(0_i128))
439
    }
440

            
441
    fn next_value(&self) -> Result<Self, NextValueError> {
442
        i128::try_from(*self)
443
            .ok()
444
            .and_then(|key| key.checked_add(1))
445
            .map(Self::from)
446
            .ok_or(NextValueError::WouldWrap)
447
    }
448
}
449

            
450
impl<'a> Key<'a> for Unsigned {
451
    type Error = std::io::Error;
452

            
453
    const LENGTH: Option<usize> = None;
454

            
455
3584
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
456
3584
        self.to_variable_vec().map(Cow::Owned)
457
3584
    }
458

            
459
3584
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
460
3584
        Self::decode_variable(bytes)
461
3584
    }
462

            
463
    fn first_value() -> Result<Self, NextValueError> {
464
        Ok(Self::from(0_u128))
465
    }
466

            
467
    fn next_value(&self) -> Result<Self, NextValueError> {
468
        u128::try_from(*self)
469
            .ok()
470
            .and_then(|key| key.checked_add(1))
471
            .map(Self::from)
472
            .ok_or(NextValueError::WouldWrap)
473
    }
474
}
475

            
476
#[cfg(feature = "uuid")]
477
impl<'k> Key<'k> for uuid::Uuid {
478
    type Error = std::array::TryFromSliceError;
479

            
480
    const LENGTH: Option<usize> = Some(16);
481

            
482
    fn as_ord_bytes(&'k self) -> Result<Cow<'k, [u8]>, Self::Error> {
483
        Ok(Cow::Borrowed(self.as_bytes()))
484
    }
485

            
486
    fn from_ord_bytes(bytes: &'k [u8]) -> Result<Self, Self::Error> {
487
        Ok(Self::from_bytes(bytes.try_into()?))
488
    }
489
}
490

            
491
impl<'a, T> Key<'a> for Option<T>
492
where
493
    T: Key<'a>,
494
{
495
    type Error = T::Error;
496

            
497
    const LENGTH: Option<usize> = T::LENGTH;
498

            
499
    /// # Panics
500
    ///
501
    /// Panics if `T::into_big_endian_bytes` returns an empty `IVec`.
502
    // TODO consider removing this panic limitation by adding a single byte to
503
    // each key (at the end preferrably) so that we can distinguish between None
504
    // and a 0-byte type
505
4222
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
506
4222
        if let Some(contents) = self {
507
3571
            let contents = contents.as_ord_bytes()?;
508
3571
            assert!(!contents.is_empty());
509
3571
            Ok(contents)
510
        } else {
511
651
            Ok(Cow::default())
512
        }
513
4222
    }
514

            
515
4351
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
516
4351
        if bytes.is_empty() {
517
1430
            Ok(None)
518
        } else {
519
2921
            Ok(Some(T::from_ord_bytes(bytes)?))
520
        }
521
4351
    }
522

            
523
    fn first_value() -> Result<Self, NextValueError> {
524
        Ok(Some(T::first_value()?))
525
    }
526

            
527
    fn next_value(&self) -> Result<Self, NextValueError> {
528
        self.as_ref().map(T::next_value).transpose()
529
    }
530
}
531

            
532
/// Adds `Key` support to an enum. Requires implementing
533
/// [`ToPrimitive`](num_traits::ToPrimitive) and
534
/// [`FromPrimitive`](num_traits::FromPrimitive), or using a crate like
535
/// [num-derive](https://crates.io/crates/num-derive) to do it automatically.
536
/// Take care when using enums as keys: if the order changes or if the meaning
537
/// of existing numerical values changes, make sure to update any related views'
538
/// version number to ensure the values are re-evaluated.
539
pub trait EnumKey: ToPrimitive + FromPrimitive + Clone + std::fmt::Debug + Send + Sync {}
540

            
541
/// An error that indicates an unexpected number of bytes were present.
542
#[derive(thiserror::Error, Debug)]
543
#[error("incorrect byte length")]
544
pub struct IncorrectByteLength;
545

            
546
/// An error that indicates an unexpected enum variant value was found.
547
#[derive(thiserror::Error, Debug)]
548
#[error("unknown enum variant")]
549
pub struct UnknownEnumVariant;
550

            
551
impl From<std::array::TryFromSliceError> for IncorrectByteLength {
552
    fn from(_: std::array::TryFromSliceError) -> Self {
553
        Self
554
    }
555
}
556

            
557
// ANCHOR: impl_key_for_enumkey
558
impl<'a, T> Key<'a> for T
559
where
560
    T: EnumKey,
561
{
562
    type Error = std::io::Error;
563
    const LENGTH: Option<usize> = None;
564

            
565
4
    fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
566
4
        let integer = self
567
4
            .to_u64()
568
4
            .map(Unsigned::from)
569
4
            .ok_or_else(|| std::io::Error::new(ErrorKind::InvalidData, IncorrectByteLength))?;
570
4
        Ok(Cow::Owned(integer.to_variable_vec()?))
571
4
    }
572

            
573
2
    fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
574
2
        let primitive = u64::decode_variable(bytes)?;
575
2
        Self::from_u64(primitive)
576
2
            .ok_or_else(|| std::io::Error::new(ErrorKind::InvalidData, UnknownEnumVariant))
577
2
    }
578
}
579
// ANCHOR_END: impl_key_for_enumkey
580

            
581
macro_rules! impl_key_for_primitive {
582
    ($type:ident) => {
583
        impl<'a> Key<'a> for $type {
584
            type Error = IncorrectByteLength;
585
            const LENGTH: Option<usize> = Some(std::mem::size_of::<$type>());
586

            
587
1529744
            fn as_ord_bytes(&'a self) -> Result<Cow<'a, [u8]>, Self::Error> {
588
1529744
                Ok(Cow::from(self.to_be_bytes().to_vec()))
589
1529744
            }
590

            
591
1442919
            fn from_ord_bytes(bytes: &'a [u8]) -> Result<Self, Self::Error> {
592
1442919
                Ok($type::from_be_bytes(bytes.try_into()?))
593
1442919
            }
594

            
595
22256
            fn first_value() -> Result<Self, NextValueError> {
596
22256
                Ok(0)
597
22256
            }
598

            
599
284076
            fn next_value(&self) -> Result<Self, NextValueError> {
600
284076
                self.checked_add(1).ok_or(NextValueError::WouldWrap)
601
284076
            }
602
        }
603
    };
604
}
605

            
606
impl_key_for_primitive!(i8);
607
impl_key_for_primitive!(u8);
608
impl_key_for_primitive!(i16);
609
impl_key_for_primitive!(u16);
610
impl_key_for_primitive!(i32);
611
impl_key_for_primitive!(u32);
612
impl_key_for_primitive!(i64);
613
impl_key_for_primitive!(u64);
614
impl_key_for_primitive!(i128);
615
impl_key_for_primitive!(u128);
616

            
617
1
#[test]
618
#[allow(clippy::cognitive_complexity)] // I disagree - @ecton
619
1
fn primitive_key_encoding_tests() -> anyhow::Result<()> {
620
1
    macro_rules! test_primitive_extremes {
621
1
        ($type:ident) => {
622
1
            assert_eq!(
623
1
                &$type::MAX.to_be_bytes(),
624
1
                $type::MAX.as_ord_bytes()?.as_ref()
625
1
            );
626
1
            assert_eq!(
627
1
                $type::MAX,
628
1
                $type::from_ord_bytes(&$type::MAX.as_ord_bytes()?)?
629
1
            );
630
1
            assert_eq!(
631
1
                $type::MIN,
632
1
                $type::from_ord_bytes(&$type::MIN.as_ord_bytes()?)?
633
1
            );
634
1
        };
635
1
    }
636
1

            
637
1
    test_primitive_extremes!(i8);
638
1
    test_primitive_extremes!(u8);
639
1
    test_primitive_extremes!(i16);
640
1
    test_primitive_extremes!(u16);
641
1
    test_primitive_extremes!(i32);
642
1
    test_primitive_extremes!(u32);
643
1
    test_primitive_extremes!(i64);
644
1
    test_primitive_extremes!(u64);
645
1
    test_primitive_extremes!(i128);
646
1
    test_primitive_extremes!(u128);
647

            
648
1
    Ok(())
649
1
}
650

            
651
1
#[test]
652
1
fn optional_key_encoding_tests() -> anyhow::Result<()> {
653
1
    assert!(Option::<i8>::None.as_ord_bytes()?.is_empty());
654
1
    assert_eq!(
655
1
        Some(1_i8),
656
1
        Option::from_ord_bytes(&Some(1_i8).as_ord_bytes()?)?
657
    );
658
1
    Ok(())
659
1
}
660

            
661
1
#[test]
662
#[allow(clippy::unit_cmp)] // this is more of a compilation test
663
1
fn unit_key_encoding_tests() -> anyhow::Result<()> {
664
1
    assert!(().as_ord_bytes()?.is_empty());
665
1
    assert_eq!((), <() as Key>::from_ord_bytes(&[])?);
666
1
    Ok(())
667
1
}
668

            
669
1
#[test]
670
#[allow(clippy::unit_cmp)] // this is more of a compilation test
671
1
fn bool_key_encoding_tests() -> anyhow::Result<()> {
672
1
    let true_as_bytes = true.as_ord_bytes()?;
673
1
    let false_as_bytes = false.as_ord_bytes()?;
674
1
    assert!(bool::from_ord_bytes(&true_as_bytes)?);
675
1
    assert!(!bool::from_ord_bytes(&false_as_bytes)?);
676
1
    Ok(())
677
1
}
678

            
679
1
#[test]
680
1
fn vec_key_encoding_tests() -> anyhow::Result<()> {
681
1
    const ORIGINAL_VALUE: &[u8] = b"bonsaidb";
682
1
    let vec = Cow::<'_, [u8]>::from(ORIGINAL_VALUE);
683
1
    assert_eq!(vec.clone(), Cow::from_ord_bytes(&vec.as_ord_bytes()?)?);
684
1
    Ok(())
685
1
}
686

            
687
1
#[test]
688
#[allow(clippy::use_self)] // Weird interaction with num_derive
689
1
fn enum_derive_tests() -> anyhow::Result<()> {
690
4
    #[derive(Debug, Clone, num_derive::ToPrimitive, num_derive::FromPrimitive)]
691
    enum SomeEnum {
692
        One = 1,
693
        NineNineNine = 999,
694
    }
695

            
696
    impl EnumKey for SomeEnum {}
697

            
698
1
    let encoded = SomeEnum::One.as_ord_bytes()?;
699
1
    let value = SomeEnum::from_ord_bytes(&encoded)?;
700
1
    assert!(matches!(value, SomeEnum::One));
701

            
702
1
    let encoded = SomeEnum::NineNineNine.as_ord_bytes()?;
703
1
    let value = SomeEnum::from_ord_bytes(&encoded)?;
704
1
    assert!(matches!(value, SomeEnum::NineNineNine));
705

            
706
1
    Ok(())
707
1
}