use fred::interfaces::KeysInterface; use fred::{clients::Pool, prelude::*}; use serde_json::Value; use sqlx::PgPool; pub type AppState = std::sync::Arc>; pub struct AppInternalState { pub database: sqlx::postgres::PgPool, pub cache: Cache, } pub struct Cache { pub inmem: Pool, } impl AppInternalState { pub fn new(database: PgPool, cache: Pool) -> Self { AppInternalState { database, cache: Cache { inmem: cache }, } } } impl Cache { pub async fn get(&mut self, key: String) -> Result, Box> where T: for<'de> serde::Deserialize<'de>, { if !self.inmem.is_connected() { return Err(Box::new("Are you connected to the cache?".into())); } let value: Option = self.inmem.get(key).await?; let result = match value { Some(x) => match serde_json::from_value(x) { Ok(x) => Some(x), Err(_) => None, }, None => None, }; Ok(result) } pub async fn set( &mut self, key: String, contents: &T, expiration: Option, set_opts: Option, get: bool, ) -> Result<(), Box> where T: for<'de> serde::Deserialize<'de>, { if !self.inmem.is_connected() { return Err(Box::new("Are you connected to the cache?".into())); } let value: Value = serde_json::to_value(contents)?; self.inmem .set(key, value.to_string(), expiration, set_opts, get) .await?; Ok(()) } pub async fn del(&mut self, key: String) -> Result<(), Box> { self.inmem.del(key).await?; Ok(()) } }