use crate::wit_bindgen;
#[doc(hidden)]
pub mod wit {
#![allow(missing_docs)]
use crate::wit_bindgen;
wit_bindgen::generate!({
runtime_path: "crate::wit_bindgen::rt",
world: "spin-sdk-kv",
path: "wit",
generate_all,
});
pub use spin::key_value::key_value;
}
#[cfg(feature = "json")]
use serde::{de::DeserializeOwned, Serialize};
#[doc(inline)]
pub use wit::key_value::Error;
pub struct Store(wit::key_value::Store);
impl Store {
pub async fn open_default() -> Result<Self, Error> {
wit::key_value::Store::open("default".into())
.await
.map(Store)
}
}
impl Store {
pub async fn open(label: impl AsRef<str>) -> Result<Self, Error> {
wit::key_value::Store::open(label.as_ref().to_string())
.await
.map(Store)
}
pub async fn get(&self, key: impl AsRef<str>) -> Result<Option<Vec<u8>>, Error> {
self.0.get(key.as_ref().to_string()).await
}
pub async fn set(&self, key: impl AsRef<str>, value: impl AsRef<[u8]>) -> Result<(), Error> {
self.0
.set(key.as_ref().to_string(), value.as_ref().to_vec())
.await
}
pub async fn delete(&self, key: impl AsRef<str>) -> Result<(), Error> {
self.0.delete(key.as_ref().to_string()).await
}
pub async fn exists(&self, key: impl AsRef<str>) -> Result<bool, Error> {
self.0.exists(key.as_ref().to_string()).await
}
pub async fn get_keys(&self) -> Keys {
let (keys, result) = self.0.get_keys().await;
Keys { keys, result }
}
#[cfg(feature = "json")]
pub async fn set_json<T: Serialize>(
&self,
key: impl AsRef<str>,
value: &T,
) -> Result<(), anyhow::Error> {
Ok(self
.0
.set(key.as_ref().to_string(), serde_json::to_vec(value)?)
.await?)
}
#[cfg(feature = "json")]
pub async fn get_json<T: DeserializeOwned>(
&self,
key: impl AsRef<str>,
) -> Result<Option<T>, anyhow::Error> {
let Some(value) = self.0.get(key.as_ref().to_string()).await? else {
return Ok(None);
};
Ok(serde_json::from_slice(&value)?)
}
}
pub struct Keys {
keys: wit_bindgen::StreamReader<String>,
result: wit_bindgen::FutureReader<Result<(), Error>>,
}
impl Keys {
pub async fn next(&mut self) -> Option<String> {
self.keys.next().await
}
pub async fn result(self) -> Result<(), Error> {
self.result.await
}
pub async fn collect(self) -> Result<Vec<String>, Error> {
let keys = self.keys.collect().await;
self.result.await?;
Ok(keys)
}
#[allow(
clippy::type_complexity,
reason = "sorry clippy that's just what the inner bits are"
)]
pub fn into_inner(
self,
) -> (
wit_bindgen::StreamReader<String>,
wit_bindgen::FutureReader<Result<(), Error>>,
) {
(self.keys, self.result)
}
}