1use crate::{Error, TransactionKind, error::mdbx_result};
2use derive_more::{Deref, DerefMut, Display};
3use std::{borrow::Cow, slice};
4use thiserror::Error;
5
6pub trait Decodable<'tx> {
8 fn decode(data_val: &[u8]) -> Result<Self, Error>
9 where
10 Self: Sized;
11
12 #[doc(hidden)]
13 unsafe fn decode_val<K: TransactionKind>(
14 _: *const ffi::MDBX_txn,
15 data_val: &ffi::MDBX_val,
16 ) -> Result<Self, Error>
17 where
18 Self: Sized,
19 {
20 let s = unsafe { slice::from_raw_parts(data_val.iov_base as *const u8, data_val.iov_len) };
21
22 Decodable::decode(s)
23 }
24}
25
26impl<'tx> Decodable<'tx> for Cow<'tx, [u8]> {
27 fn decode(_: &[u8]) -> Result<Self, Error> {
28 unreachable!()
29 }
30
31 #[doc(hidden)]
32 unsafe fn decode_val<K: TransactionKind>(
33 txn: *const ffi::MDBX_txn,
34 data_val: &ffi::MDBX_val,
35 ) -> Result<Self, Error> {
36 let is_dirty =
37 (!K::ONLY_CLEAN) && mdbx_result(unsafe { ffi::mdbx_is_dirty(txn, data_val.iov_base) })?;
38
39 let s = unsafe { slice::from_raw_parts(data_val.iov_base as *const u8, data_val.iov_len) };
40
41 Ok(if is_dirty {
42 Cow::Owned(s.to_vec())
43 } else {
44 Cow::Borrowed(s)
45 })
46 }
47}
48
49#[cfg(feature = "lifetimed-bytes")]
50impl<'tx> Decodable<'tx> for lifetimed_bytes::Bytes<'tx> {
51 fn decode(_: &[u8]) -> Result<Self, Error> {
52 unreachable!()
53 }
54
55 #[doc(hidden)]
56 unsafe fn decode_val<K: TransactionKind>(
57 txn: *const ffi::MDBX_txn,
58 data_val: &ffi::MDBX_val,
59 ) -> Result<Self, Error> {
60 unsafe { Cow::<'tx, [u8]>::decode_val::<K>(txn, data_val).map(From::from) }
61 }
62}
63
64impl Decodable<'_> for Vec<u8> {
65 fn decode(data_val: &[u8]) -> Result<Self, Error>
66 where
67 Self: Sized,
68 {
69 Ok(data_val.to_vec())
70 }
71}
72
73impl Decodable<'_> for () {
74 fn decode(_: &[u8]) -> Result<Self, Error> {
75 Ok(())
76 }
77
78 unsafe fn decode_val<K: TransactionKind>(
79 _: *const ffi::MDBX_txn,
80 _: &ffi::MDBX_val,
81 ) -> Result<Self, Error> {
82 Ok(())
83 }
84}
85
86#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Deref, DerefMut)]
88pub struct ObjectLength(pub usize);
89
90impl Decodable<'_> for ObjectLength {
91 fn decode(data_val: &[u8]) -> Result<Self, Error>
92 where
93 Self: Sized,
94 {
95 Ok(Self(data_val.len()))
96 }
97}
98
99impl<const LEN: usize> Decodable<'_> for [u8; LEN] {
100 fn decode(data_val: &[u8]) -> Result<Self, Error>
101 where
102 Self: Sized,
103 {
104 #[derive(Clone, Debug, Display, Error)]
105 struct InvalidSize<const LEN: usize> {
106 got: usize,
107 }
108
109 if data_val.len() != LEN {
110 return Err(Error::DecodeError(Box::new(InvalidSize::<LEN> {
111 got: data_val.len(),
112 })));
113 }
114 let mut a = [0; LEN];
115 a[..].copy_from_slice(data_val);
116 Ok(a)
117 }
118}