momento_functions_host/cache.rs
1//! Host interfaces for working with Momento Cache apis
2
3use std::time::Duration;
4
5use crate::encoding::{Encode, EncodeError, Extract, ExtractError};
6use momento_functions_wit::host::momento::functions::cache_scalar;
7
8/// An error occurred when setting a value in the cache.
9#[derive(thiserror::Error, Debug)]
10pub enum CacheSetError<E: EncodeError> {
11 /// The provided value could not be encoded.
12 #[error("Failed to encode value.")]
13 EncodeFailed {
14 /// The underlying encoding error.
15 cause: E,
16 },
17 /// An error occurred when calling the host cache function.
18 #[error(transparent)]
19 CacheError(#[from] cache_scalar::Error),
20}
21
22/// An error occurred when getting a value from the cache.
23#[derive(thiserror::Error, Debug)]
24pub enum CacheGetError<E: ExtractError> {
25 /// The value could not be extracted with the provided implementation.
26 #[error("Failed to extract value.")]
27 ExtractFailed {
28 /// The underlying error.
29 cause: E,
30 },
31 /// An error occurred when calling the host cache function.
32 #[error(transparent)]
33 CacheError(#[from] cache_scalar::Error),
34}
35/// Get a value from the cache.
36///
37/// Examples:
38/// ________
39/// Bytes:
40/// ```rust
41/// # use momento_functions_host::cache;
42/// # use momento_functions_host::cache::CacheGetError;
43///
44/// # fn f() -> Result<(), CacheGetError<Vec<u8>>> {
45/// let value: Option<Vec<u8>> = cache::get("my_key")?;
46/// # Ok(()) }
47/// ```
48/// ________
49/// Json:
50/// ```rust
51/// # use momento_functions_host::cache;
52/// # use momento_functions_host::cache::CacheGetError;
53/// use momento_functions_host::encoding::Json;
54///
55/// #[derive(serde::Deserialize)]
56/// struct MyStruct {
57/// message: String
58/// }
59///
60/// # fn f() -> Result<(), CacheGetError<Json<MyStruct>>> {
61/// let value: Option<Json<MyStruct>> = cache::get("my_key")?;
62/// # Ok(()) }
63/// ```
64pub fn get<T: Extract>(key: impl AsRef<[u8]>) -> Result<Option<T>, CacheGetError<T::Error>> {
65 match cache_scalar::get(key.as_ref())? {
66 Some(v) => T::extract(v)
67 .map(Some)
68 .map_err(|e| CacheGetError::ExtractFailed { cause: e }),
69 None => Ok(None),
70 }
71}
72
73/// Set a value in the cache with a time-to-live.
74///
75/// Examples:
76/// ________
77/// Bytes:
78/// ```rust
79/// # use momento_functions_host::cache;
80/// # use momento_functions_host::cache::CacheSetError;
81/// # use std::time::Duration;
82///
83/// # fn f() -> Result<(), CacheSetError<&'static str>> {
84/// cache::set(
85/// "my_key",
86/// b"hello".to_vec(),
87/// Duration::from_secs(60),
88/// )?;
89/// # Ok(()) }
90/// ```
91/// ________
92/// Json:
93/// ```rust
94/// # use momento_functions_host::cache;
95/// # use momento_functions_host::cache::CacheSetError;
96/// # use std::time::Duration;
97/// use momento_functions_host::encoding::Json;
98///
99/// #[derive(serde::Serialize)]
100/// struct MyStruct {
101/// hello: String
102/// }
103///
104/// # fn f() -> Result<(), CacheSetError<Json<MyStruct>>> {
105/// cache::set(
106/// "my_key",
107/// Json(MyStruct { hello: "hello".to_string() }),
108/// Duration::from_secs(60),
109/// )?;
110/// # Ok(()) }
111/// ```
112pub fn set<E: Encode>(
113 key: impl AsRef<[u8]>,
114 value: E,
115 ttl: Duration,
116) -> Result<(), CacheSetError<E::Error>> {
117 cache_scalar::set(
118 key.as_ref(),
119 &value
120 .try_serialize()
121 .map_err(|e| CacheSetError::EncodeFailed { cause: e })?
122 .into(),
123 saturate_ttl(ttl),
124 )
125 .map_err(Into::into)
126}
127
128fn saturate_ttl(ttl: Duration) -> u64 {
129 ttl.as_millis().clamp(0, u64::MAX as u128) as u64
130}