From e6ba0a002f2b78e5f43c9a43a569301d4d39fdaf Mon Sep 17 00:00:00 2001
From: naskya <m@naskya.net>
Date: Sat, 4 May 2024 13:19:14 +0900
Subject: [PATCH] refactor (backend-rs): add cache::{get_one, set_one,
 delete_one}

---
 packages/backend-rs/src/database/cache.rs     | 32 +++++++++++++++++++
 .../backend-rs/src/misc/get_image_size.rs     | 23 +++++++------
 2 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs
index aaf89bde86..cbc7a60ff6 100644
--- a/packages/backend-rs/src/database/cache.rs
+++ b/packages/backend-rs/src/database/cache.rs
@@ -2,6 +2,12 @@ use crate::database::{redis_conn, redis_key};
 use redis::{Commands, RedisError};
 use serde::{Deserialize, Serialize};
 
+#[derive(strum::Display)]
+pub enum Category {
+    #[strum(serialize = "fetchUrl")]
+    FetchUrl,
+}
+
 #[derive(thiserror::Error, Debug)]
 pub enum Error {
     #[error("Redis error: {0}")]
@@ -12,6 +18,10 @@ pub enum Error {
     DeserializeError(#[from] rmp_serde::decode::Error),
 }
 
+fn categorize(category: Category, key: &str) -> String {
+    format!("{}:{}", category, key)
+}
+
 fn prefix_key(key: &str) -> String {
     redis_key(format!("cache:{}", key))
 }
@@ -41,6 +51,28 @@ pub fn delete(key: &str) -> Result<(), Error> {
     Ok(redis_conn()?.del(prefix_key(key))?)
 }
 
+pub fn set_one<V: for<'a> Deserialize<'a> + Serialize>(
+    category: Category,
+    key: &str,
+    value: &V,
+    expire_seconds: u64,
+) -> Result<(), Error> {
+    set(&categorize(category, key), value, expire_seconds)
+}
+
+pub fn get_one<V: for<'a> Deserialize<'a> + Serialize>(
+    category: Category,
+    key: &str,
+) -> Result<Option<V>, Error> {
+    get(&categorize(category, key))
+}
+
+pub fn delete_one(category: Category, key: &str) -> Result<(), Error> {
+    delete(&categorize(category, key))
+}
+
+// TODO: set_all(), get_all(), delete_all()
+
 #[cfg(test)]
 mod unit_test {
     use super::{get, set};
diff --git a/packages/backend-rs/src/misc/get_image_size.rs b/packages/backend-rs/src/misc/get_image_size.rs
index ef8b7db79f..ac0de89015 100644
--- a/packages/backend-rs/src/misc/get_image_size.rs
+++ b/packages/backend-rs/src/misc/get_image_size.rs
@@ -50,11 +50,10 @@ pub async fn get_image_size_from_url(url: &str) -> Result<ImageSize, Error> {
     {
         let _ = MTX_GUARD.lock().await;
 
-        let key = format!("fetchImage:{}", url);
-        attempted = cache::get::<bool>(&key)?.is_some();
+        attempted = cache::get_one::<bool>(cache::Category::FetchUrl, url)?.is_some();
 
         if !attempted {
-            cache::set(&key, &true, 10 * 60)?;
+            cache::set_one(cache::Category::FetchUrl, url, &true, 10 * 60)?;
         }
     }
 
@@ -126,15 +125,15 @@ mod unit_test {
 
         // Delete caches in case you run this test multiple times
         // (should be disabled in CI tasks)
-        cache::delete(&format!("fetchImage:{}", png_url_1)).unwrap();
-        cache::delete(&format!("fetchImage:{}", png_url_2)).unwrap();
-        cache::delete(&format!("fetchImage:{}", png_url_3)).unwrap();
-        cache::delete(&format!("fetchImage:{}", rotated_jpeg_url)).unwrap();
-        cache::delete(&format!("fetchImage:{}", webp_url_1)).unwrap();
-        cache::delete(&format!("fetchImage:{}", webp_url_2)).unwrap();
-        cache::delete(&format!("fetchImage:{}", ico_url)).unwrap();
-        cache::delete(&format!("fetchImage:{}", gif_url)).unwrap();
-        cache::delete(&format!("fetchImage:{}", mp3_url)).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, png_url_1).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, png_url_2).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, png_url_3).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, rotated_jpeg_url).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, webp_url_1).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, webp_url_2).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, ico_url).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, gif_url).unwrap();
+        cache::delete_one(cache::Category::FetchUrl, mp3_url).unwrap();
 
         let png_size_1 = ImageSize {
             width: 1024,