Created
September 12, 2022 10:40
-
-
Save nmrshll/b0a052ef1f90e036f76ddf85f8704e34 to your computer and use it in GitHub Desktop.
Rust field cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::future::Future; | |
use tokio::sync::RwLock; | |
pub struct Cache<T: Clone> { | |
item: RwLock<Option<T>>, | |
} | |
impl<T: Clone> Cache<T> { | |
pub fn new() -> Self { | |
Cache { | |
item: RwLock::new(None), | |
} | |
} | |
pub async fn get(&self) -> Option<T> { | |
let guard = self.item.read().await; | |
let inner = guard.clone(); | |
inner | |
} | |
async fn set(&self, val: T) -> T { | |
let mut w_guard = self.item.write().await; | |
*w_guard = Some(val.clone()); | |
val | |
} | |
pub async fn get_or_set(&self, val: T) -> T { | |
if let Some(inner) = self.item.read().await.clone() { | |
return inner; | |
} // read ref is dropped here | |
self.set(val).await | |
} | |
pub async fn get_or_init(&self, init: impl Future<Output = T>) -> T { | |
if let Some(inner) = self.item.read().await.clone() { | |
return inner; | |
} // read ref is dropped here | |
let new_val = init.await; | |
self.set(new_val).await | |
} | |
} | |
mod tests { | |
use super::Cache; | |
#[tokio::test] | |
async fn test_cache() { | |
let cache: Cache<String> = Cache::new(); | |
let out = cache.get_or_set("hello".to_string()).await; | |
assert_eq!(out, "hello".to_string()); | |
let out2 = cache.get_or_set("world".to_string()).await; | |
assert_eq!(out2, "hello".to_string()); | |
let out3 = cache.get().await; | |
assert_eq!(out3, Some("hello".to_string())); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment