spin_sdk/
key_value.rs

1//! Spin key-value persistent storage
2//!
3//! This module provides a generic interface for key-value storage, which may be implemented by the host various
4//! ways (e.g. via an in-memory table, a local file, or a remote database). Details such as consistency model and
5//! durability will depend on the implementation and may vary from one to store to the next.
6//!
7//! # Examples
8//!
9//! Open the default store and set the 'message' key:
10//!
11//! ```no_run
12//! # fn main() -> anyhow::Result<()> {
13//! let store = spin_sdk::key_value::Store::open_default()?;
14//! store.set("message", "Hello world".as_bytes())?;
15//! # Ok(())
16//! # }
17//! ```
18
19use super::wit::v2::key_value;
20
21#[cfg(feature = "json")]
22use serde::{de::DeserializeOwned, Serialize};
23
24#[doc(inline)]
25pub use key_value::Error;
26
27/// An open key-value store.
28///
29/// # Examples
30///
31/// Open the default store and set the 'message' key:
32///
33/// ```no_run
34/// # fn main() -> anyhow::Result<()> {
35/// let store = spin_sdk::key_value::Store::open_default()?;
36/// store.set("message", "Hello world".as_bytes())?;
37/// # Ok(())
38/// # }
39/// ```
40///
41/// Open the default store and get the 'message' key:
42///
43/// ```no_run
44/// # fn main() -> anyhow::Result<()> {
45/// let store = spin_sdk::key_value::Store::open_default()?;
46/// let message = store.get("message")?;
47/// let response = message.unwrap_or_else(|| "not found".into());
48/// # Ok(())
49/// # }
50/// ```
51///
52/// Open a named store and list all the keys defined in it:
53///
54/// ```no_run
55/// # fn main() -> anyhow::Result<()> {
56/// let store = spin_sdk::key_value::Store::open("finance")?;
57/// let keys = store.get_keys()?;
58/// # Ok(())
59/// # }
60/// ```
61///
62/// Open the default store and delete the 'message' key:
63///
64/// ```no_run
65/// # fn main() -> anyhow::Result<()> {
66/// let store = spin_sdk::key_value::Store::open_default()?;
67/// store.delete("message")?;
68/// # Ok(())
69/// # }
70/// ```
71#[doc(inline)]
72pub use key_value::Store;
73
74impl Store {
75    /// Open the default store.
76    ///
77    /// This is equivalent to `Store::open("default")`.
78    pub fn open_default() -> Result<Self, Error> {
79        Self::open("default")
80    }
81}
82
83impl Store {
84    #[cfg(feature = "json")]
85    /// Serialize the given data to JSON, then set it as the value for the specified `key`.
86    ///
87    /// # Examples
88    ///
89    /// Open the default store and save a customer information document against the customer ID:
90    ///
91    /// ```no_run
92    /// # use serde::{Deserialize, Serialize};
93    /// #[derive(Deserialize, Serialize)]
94    /// struct Customer {
95    ///     name: String,
96    ///     address: Vec<String>,
97    /// }
98    ///
99    /// # fn main() -> anyhow::Result<()> {
100    /// let customer_id = "CR1234567";
101    /// let customer = Customer {
102    ///     name: "Alice".to_owned(),
103    ///     address: vec!["Wonderland Way".to_owned()],
104    /// };
105    ///
106    /// let store = spin_sdk::key_value::Store::open_default()?;
107    /// store.set_json(customer_id, &customer)?;
108    /// # Ok(())
109    /// # }
110    /// ```
111    pub fn set_json<T: Serialize>(
112        &self,
113        key: impl AsRef<str>,
114        value: &T,
115    ) -> Result<(), anyhow::Error> {
116        Ok(self.set(key.as_ref(), &serde_json::to_vec(value)?)?)
117    }
118
119    #[cfg(feature = "json")]
120    /// Deserialize an instance of type `T` from the value of `key`.
121    ///
122    /// # Examples
123    ///
124    /// Open the default store and retrieve a customer information document by customer ID:
125    ///
126    /// ```no_run
127    /// # use serde::{Deserialize, Serialize};
128    /// #[derive(Deserialize, Serialize)]
129    /// struct Customer {
130    ///     name: String,
131    ///     address: Vec<String>,
132    /// }
133    ///
134    /// # fn main() -> anyhow::Result<()> {
135    /// let customer_id = "CR1234567";
136    ///
137    /// let store = spin_sdk::key_value::Store::open_default()?;
138    /// let customer = store.get_json::<Customer>(customer_id)?;
139    /// # Ok(())
140    /// # }
141    /// ```
142    pub fn get_json<T: DeserializeOwned>(
143        &self,
144        key: impl AsRef<str>,
145    ) -> Result<Option<T>, anyhow::Error> {
146        let Some(value) = self.get(key.as_ref())? else {
147            return Ok(None);
148        };
149        Ok(serde_json::from_slice(&value)?)
150    }
151}