libmdbx_remote/
codec.rs

1use crate::{Error, TransactionKind};
2use derive_more::{Debug, Deref, DerefMut};
3use std::{borrow::Cow, slice};
4
5/// Implement this to be able to decode data values
6pub trait TableObject: Sized {
7    /// Decodes the object from the given bytes.
8    fn decode(data_val: &[u8]) -> Result<Self, Error>;
9
10    /// Decodes the value directly from the given MDBX_val pointer.
11    ///
12    /// # Safety
13    ///
14    /// This should only in the context of an MDBX transaction.
15    #[doc(hidden)]
16    unsafe fn decode_val<K: TransactionKind>(
17        _: *const ffi::MDBX_txn,
18        data_val: ffi::MDBX_val,
19    ) -> Result<Self, Error> {
20        let s = slice::from_raw_parts(data_val.iov_base as *const u8, data_val.iov_len);
21        Self::decode(s)
22    }
23}
24
25impl TableObject for Cow<'_, [u8]> {
26    fn decode(bs: &[u8]) -> Result<Self, Error> {
27        // unreachable!()
28        // Ok(Self::Borrowed(bs)) // liftime issues, shit
29        Ok(Cow::Owned(bs.to_vec()))
30    }
31
32    #[doc(hidden)]
33    unsafe fn decode_val<K: TransactionKind>(
34        _txn: *const ffi::MDBX_txn,
35        data_val: ffi::MDBX_val,
36    ) -> Result<Self, Error> {
37        let s = slice::from_raw_parts(data_val.iov_base as *const u8, data_val.iov_len);
38
39        #[cfg(feature = "return-borrowed")]
40        {
41            Ok(Cow::Borrowed(s))
42        }
43
44        #[cfg(not(feature = "return-borrowed"))]
45        {
46            let is_dirty = (!K::IS_READ_ONLY)
47                && crate::error::mdbx_result(ffi::mdbx_is_dirty(_txn, data_val.iov_base))?;
48
49            Ok(if is_dirty {
50                Cow::Owned(s.to_vec())
51            } else {
52                Cow::Borrowed(s)
53            })
54        }
55    }
56}
57
58impl TableObject for Vec<u8> {
59    fn decode(data_val: &[u8]) -> Result<Self, Error> {
60        Ok(data_val.to_vec())
61    }
62}
63
64impl TableObject for () {
65    fn decode(_: &[u8]) -> Result<Self, Error> {
66        Ok(())
67    }
68
69    unsafe fn decode_val<K: TransactionKind>(
70        _: *const ffi::MDBX_txn,
71        _: ffi::MDBX_val,
72    ) -> Result<Self, Error> {
73        Ok(())
74    }
75}
76
77/// If you don't need the data itself, just its length.
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Deref, DerefMut)]
79pub struct ObjectLength(pub usize);
80
81impl TableObject for ObjectLength {
82    fn decode(data_val: &[u8]) -> Result<Self, Error> {
83        Ok(Self(data_val.len()))
84    }
85}
86
87impl<const LEN: usize> TableObject for [u8; LEN] {
88    fn decode(data_val: &[u8]) -> Result<Self, Error> {
89        if data_val.len() != LEN {
90            return Err(Error::DecodeErrorLenDiff);
91        }
92        let mut a = [0; LEN];
93        a[..].copy_from_slice(data_val);
94        Ok(a)
95    }
96}