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}