From 06eca4f3410523109b16582510c57ac5e03fa9c3 Mon Sep 17 00:00:00 2001
From: librelois <c@elo.tf>
Date: Sat, 5 Jun 2021 20:57:53 +0200
Subject: [PATCH] ref(kv_typed): get_ref_slice: deser must be backend agnostic

---
 tools/kv_typed/src/backend.rs                 |  2 +-
 tools/kv_typed/src/backend/leveldb.rs         | 18 ++-------------
 tools/kv_typed/src/backend/lmdb.rs            | 18 ++-------------
 tools/kv_typed/src/backend/memory.rs          | 23 ++-----------------
 .../kv_typed/src/backend/memory_singleton.rs  | 19 ++-------------
 tools/kv_typed/src/backend/sled.rs            | 23 ++-----------------
 tools/kv_typed/src/collection_ro.rs           | 14 ++++++++++-
 tools/kv_typed/src/transactional_read.rs      | 14 ++++++++++-
 tools/kv_typed/src/transactional_write.rs     | 14 ++++++++++-
 9 files changed, 50 insertions(+), 95 deletions(-)

diff --git a/tools/kv_typed/src/backend.rs b/tools/kv_typed/src/backend.rs
index 5e91cc2..a1f0f7d 100644
--- a/tools/kv_typed/src/backend.rs
+++ b/tools/kv_typed/src/backend.rs
@@ -49,7 +49,7 @@ pub trait BackendCol: 'static + Clone + Debug + Send + Sync {
         k: &K,
         f: F,
     ) -> KvResult<Option<D>>;
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         k: &K,
         f: F,
diff --git a/tools/kv_typed/src/backend/leveldb.rs b/tools/kv_typed/src/backend/leveldb.rs
index 22692c7..e2f4a45 100644
--- a/tools/kv_typed/src/backend/leveldb.rs
+++ b/tools/kv_typed/src/backend/leveldb.rs
@@ -162,7 +162,7 @@ impl BackendCol for LevelDbCol {
         })
     }
     #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         k: &K,
         f: F,
@@ -170,21 +170,7 @@ impl BackendCol for LevelDbCol {
         k.as_bytes(|k_bytes| {
             self.0
                 .get(ReadOptions::new(), k_bytes)?
-                .map(|bytes| {
-                    if bytes.is_empty() {
-                        f(&[])
-                    } else if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
+                .map(|bytes| f(&bytes))
                 .transpose()
         })
     }
diff --git a/tools/kv_typed/src/backend/lmdb.rs b/tools/kv_typed/src/backend/lmdb.rs
index e305328..bf329ff 100644
--- a/tools/kv_typed/src/backend/lmdb.rs
+++ b/tools/kv_typed/src/backend/lmdb.rs
@@ -312,7 +312,7 @@ impl BackendCol for LmdbCol {
         })
     }
 
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         k: &K,
         f: F,
@@ -323,21 +323,7 @@ impl BackendCol for LmdbCol {
             access
                 .get::<_, [u8]>(&self.inner.tree, k_bytes)
                 .to_opt()?
-                .map(|bytes| {
-                    if bytes.is_empty() {
-                        f(&[])
-                    } else if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
+                .map(|bytes| f(bytes))
                 .transpose()
         })
     }
diff --git a/tools/kv_typed/src/backend/memory.rs b/tools/kv_typed/src/backend/memory.rs
index 0d50e78..ed32538 100644
--- a/tools/kv_typed/src/backend/memory.rs
+++ b/tools/kv_typed/src/backend/memory.rs
@@ -129,31 +129,12 @@ impl BackendCol for MemCol {
         })
     }
     #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         k: &K,
         f: F,
     ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.tree
-                .get(k_bytes)
-                .map(|bytes| {
-                    if bytes.is_empty() {
-                        f(&[])
-                    } else if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
+        k.as_bytes(|k_bytes| self.tree.get(k_bytes).map(|bytes| f(bytes)).transpose())
     }
     #[inline(always)]
     fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
diff --git a/tools/kv_typed/src/backend/memory_singleton.rs b/tools/kv_typed/src/backend/memory_singleton.rs
index 786ca4e..8a9afc5 100644
--- a/tools/kv_typed/src/backend/memory_singleton.rs
+++ b/tools/kv_typed/src/backend/memory_singleton.rs
@@ -113,27 +113,12 @@ impl BackendCol for MemCol {
             .transpose()
     }
     #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         _k: &K,
         f: F,
     ) -> KvResult<Option<D>> {
-        self.0
-            .as_ref()
-            .map(|bytes| {
-                if bytes.is_empty() {
-                    f(&[])
-                } else if let Some(layout_verified) =
-                    zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
-                {
-                    f(&layout_verified)
-                } else {
-                    Err(KvError::DeserError(
-                        "Bytes are invalid length or alignment.".into(),
-                    ))
-                }
-            })
-            .transpose()
+        self.0.as_ref().map(|bytes| f(bytes)).transpose()
     }
     #[inline(always)]
     fn delete<K: Key>(&mut self, _k: &K) -> KvResult<()> {
diff --git a/tools/kv_typed/src/backend/sled.rs b/tools/kv_typed/src/backend/sled.rs
index 9d13580..43bab2a 100644
--- a/tools/kv_typed/src/backend/sled.rs
+++ b/tools/kv_typed/src/backend/sled.rs
@@ -112,31 +112,12 @@ impl BackendCol for SledCol {
         })
     }
     #[inline(always)]
-    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
+    fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[u8]) -> KvResult<D>>(
         &self,
         k: &K,
         f: F,
     ) -> KvResult<Option<D>> {
-        k.as_bytes(|k_bytes| {
-            self.0
-                .get(k_bytes)?
-                .map(|bytes| {
-                    if bytes.is_empty() {
-                        f(&[])
-                    } else if let Some(layout_verified) =
-                        zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
-                            &bytes[V::prefix_len()..],
-                        )
-                    {
-                        f(&layout_verified)
-                    } else {
-                        Err(KvError::DeserError(
-                            "Bytes are invalid length or alignment.".into(),
-                        ))
-                    }
-                })
-                .transpose()
-        })
+        k.as_bytes(|k_bytes| self.0.get(k_bytes)?.map(|bytes| f(&bytes)).transpose())
     }
     #[inline(always)]
     fn delete<K: Key>(&mut self, k: &K) -> KvResult<()> {
diff --git a/tools/kv_typed/src/collection_ro.rs b/tools/kv_typed/src/collection_ro.rs
index 1ab5360..3a1aa0c 100644
--- a/tools/kv_typed/src/collection_ro.rs
+++ b/tools/kv_typed/src/collection_ro.rs
@@ -192,7 +192,19 @@ impl<V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> DbCollectionRoGetRef
         f: F,
     ) -> KvResult<Option<D>> {
         let r = self.inner.read();
-        r.backend_col.get_ref_slice::<E::K, V, D, F>(k, f)
+        r.backend_col.get_ref_slice::<E::K, V, D, _>(k, |bytes| {
+            if bytes.is_empty() {
+                f(&[])
+            } else if let Some(layout_verified) =
+                zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
+            {
+                f(&layout_verified)
+            } else {
+                Err(KvError::DeserError(
+                    "Bytes are invalid length or alignment.".into(),
+                ))
+            }
+        })
     }
 }
 
diff --git a/tools/kv_typed/src/transactional_read.rs b/tools/kv_typed/src/transactional_read.rs
index 647861f..75df9be 100644
--- a/tools/kv_typed/src/transactional_read.rs
+++ b/tools/kv_typed/src/transactional_read.rs
@@ -137,7 +137,19 @@ impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC
     ) -> KvResult<Option<D>> {
         self.col_reader
             .backend_col
-            .get_ref_slice::<E::K, V, D, F>(k, f)
+            .get_ref_slice::<E::K, V, D, _>(k, |bytes| {
+                if bytes.is_empty() {
+                    f(&[])
+                } else if let Some(layout_verified) =
+                    zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
+                {
+                    f(&layout_verified)
+                } else {
+                    Err(KvError::DeserError(
+                        "Bytes are invalid length or alignment.".into(),
+                    ))
+                }
+            })
     }
 }
 
diff --git a/tools/kv_typed/src/transactional_write.rs b/tools/kv_typed/src/transactional_write.rs
index 2595e63..54d109d 100644
--- a/tools/kv_typed/src/transactional_write.rs
+++ b/tools/kv_typed/src/transactional_write.rs
@@ -61,7 +61,19 @@ impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC
     ) -> KvResult<Option<D>> {
         self.col_reader
             .backend_col
-            .get_ref_slice::<E::K, V, D, F>(k, f)
+            .get_ref_slice::<E::K, V, D, _>(k, |bytes| {
+                if bytes.is_empty() {
+                    f(&[])
+                } else if let Some(layout_verified) =
+                    zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
+                {
+                    f(&layout_verified)
+                } else {
+                    Err(KvError::DeserError(
+                        "Bytes are invalid length or alignment.".into(),
+                    ))
+                }
+            })
     }
 }
 
-- 
GitLab