Skip to content

Commit e055bed

Browse files
committed
kv: automatic key and value serialization
1 parent 03d3fc1 commit e055bed

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

src/kv.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{get_blob, Message, PackageId, Request};
2-
use serde::{Deserialize, Serialize};
2+
use serde::{de::DeserializeOwned, Deserialize, Serialize};
3+
use std::marker::PhantomData;
34
use thiserror::Error;
45

56
/// Actions are sent to a specific key value database, "db" is the name,
@@ -54,15 +55,21 @@ pub enum KvError {
5455
/// Opening or creating a kv will give you a Result<Kv>.
5556
/// You can call it's impl functions to interact with it.
5657
#[derive(Debug, Serialize, Deserialize)]
57-
pub struct Kv {
58+
pub struct Kv<K, V> {
5859
pub package_id: PackageId,
5960
pub db: String,
6061
pub timeout: u64,
62+
_marker: PhantomData<(K, V)>,
6163
}
6264

63-
impl Kv {
65+
impl<K, V> Kv<K, V>
66+
where
67+
K: Serialize + DeserializeOwned,
68+
V: Serialize + DeserializeOwned,
69+
{
6470
/// Get a value.
65-
pub fn get(&self, key: Vec<u8>) -> anyhow::Result<Vec<u8>> {
71+
pub fn get(&self, key: &K) -> anyhow::Result<V> {
72+
let key = serde_json::to_vec(key)?;
6673
let res = Request::new()
6774
.target(("our", "kv", "distro", "sys"))
6875
.body(serde_json::to_vec(&KvRequest {
@@ -82,7 +89,9 @@ impl Kv {
8289
Some(bytes) => bytes.bytes,
8390
None => return Err(anyhow::anyhow!("kv: no blob")),
8491
};
85-
Ok(bytes)
92+
let value = serde_json::from_slice::<V>(&bytes)
93+
.map_err(|e| anyhow::anyhow!("Failed to deserialize value: {}", e))?;
94+
Ok(value)
8695
}
8796
KvResponse::Err { error } => Err(error.into()),
8897
_ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)),
@@ -93,7 +102,10 @@ impl Kv {
93102
}
94103

95104
/// Set a value, optionally in a transaction.
96-
pub fn set(&self, key: Vec<u8>, value: Vec<u8>, tx_id: Option<u64>) -> anyhow::Result<()> {
105+
pub fn set(&self, key: &K, value: &V, tx_id: Option<u64>) -> anyhow::Result<()> {
106+
let key = serde_json::to_vec(key)?;
107+
let value = serde_json::to_vec(value)?;
108+
97109
let res = Request::new()
98110
.target(("our", "kv", "distro", "sys"))
99111
.body(serde_json::to_vec(&KvRequest {
@@ -119,7 +131,8 @@ impl Kv {
119131
}
120132

121133
/// Delete a value, optionally in a transaction.
122-
pub fn delete(&self, key: Vec<u8>, tx_id: Option<u64>) -> anyhow::Result<()> {
134+
pub fn delete(&self, key: &K, tx_id: Option<u64>) -> anyhow::Result<()> {
135+
let key = serde_json::to_vec(key)?;
123136
let res = Request::new()
124137
.target(("our", "kv", "distro", "sys"))
125138
.body(serde_json::to_vec(&KvRequest {
@@ -195,7 +208,11 @@ impl Kv {
195208
}
196209

197210
/// Opens or creates a kv db.
198-
pub fn open(package_id: PackageId, db: &str, timeout: Option<u64>) -> anyhow::Result<Kv> {
211+
pub fn open<K, V>(package_id: PackageId, db: &str, timeout: Option<u64>) -> anyhow::Result<Kv<K, V>>
212+
where
213+
K: Serialize + DeserializeOwned,
214+
V: Serialize + DeserializeOwned,
215+
{
199216
let timeout = timeout.unwrap_or(5);
200217

201218
let res = Request::new()
@@ -216,6 +233,7 @@ pub fn open(package_id: PackageId, db: &str, timeout: Option<u64>) -> anyhow::Re
216233
package_id,
217234
db: db.to_string(),
218235
timeout,
236+
_marker: PhantomData,
219237
}),
220238
KvResponse::Err { error } => Err(error.into()),
221239
_ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)),

0 commit comments

Comments
 (0)