From abb999e3f2d7700dc60c4bd35b86599e575614d2 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sat, 20 Apr 2024 14:17:07 +0100 Subject: [PATCH] more wip --- Cargo.lock | 286 +++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 + src/avatar_cache.rs | 44 +++++++ src/main.rs | 79 ++---------- src/user_data.rs | 39 ++++++ 5 files changed, 383 insertions(+), 67 deletions(-) create mode 100644 src/avatar_cache.rs create mode 100644 src/user_data.rs diff --git a/Cargo.lock b/Cargo.lock index 5c52f55..e81a71b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,37 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aliri_braid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df233d014e7a9ad9693f08f17eb198251fb75d94c345dcfa4bdedfecc67f24fb" +dependencies = [ + "aliri_braid_impl", +] + +[[package]] +name = "aliri_braid_impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1eb7c4fcde1858a6796c18a729b661346d38e05a207e2d9028bce822fc20283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "bytes" version = "1.6.0" @@ -18,6 +49,23 @@ dependencies = [ "memchr", ] +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -27,6 +75,23 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "idna" version = "0.5.0" @@ -49,18 +114,69 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redis" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "152f3863635cbb76b73bc247845781098302c6c9ad2060e1a9a7de56840346b6" +dependencies = [ + "async-trait", + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1", + "url", +] + [[package]] name = "redis" version = "0.25.3" @@ -76,11 +192,25 @@ dependencies = [ "url", ] +[[package]] +name = "redis-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd54aa405add884ec36f7eb40d6d09d5be4ea6b69655492dd5764bc7d698ef12" +dependencies = [ + "heck", + "quote", + "redis 0.21.7", + "syn 1.0.109", +] + [[package]] name = "rust-twitch-avatar-cache" version = "0.1.0" dependencies = [ - "redis", + "redis 0.25.3", + "redis-derive", + "twitch_api", ] [[package]] @@ -89,6 +219,35 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -105,6 +264,48 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -120,12 +321,89 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "twitch_api" +version = "0.7.0-rc.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08be17cac4dd00fc643cb21adc349573a4b882e07d296ca5b4b0178343d48b42" +dependencies = [ + "aliri_braid", + "displaydoc", + "http", + "once_cell", + "serde", + "thiserror", + "tower", + "twitch_types", + "url", + "version_check", +] + +[[package]] +name = "twitch_types" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15ebccdc5907cf895c4624502df6e21e38faf4c55d722bd60ceae48178d9f0e9" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "unicode-bidi" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + [[package]] name = "unicode-normalization" version = "0.1.23" @@ -146,6 +424,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index f94c595..a3123c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2021" [dependencies] redis = "0.25.3" +redis-derive = "0.1.7" +twitch_api = "0.7.0-rc.7" diff --git a/src/avatar_cache.rs b/src/avatar_cache.rs new file mode 100644 index 0000000..94c241f --- /dev/null +++ b/src/avatar_cache.rs @@ -0,0 +1,44 @@ +use redis::{Commands, RedisResult}; +use crate::user_data::UserData; + +pub struct AvatarCache { + redis: redis::Client, + timeout: i64, +} + +impl AvatarCache { + pub(crate) fn new(redis: redis::Client, timeout: i64) -> Self { + AvatarCache { + redis, + timeout, + } + } + + /// Get user data from Cache + pub(crate) fn get_cache_by_name(&self, name: &str) -> RedisResult { + let mut con = self.redis.get_connection()?; + + con.hgetall(UserData::redis_id_from_str(name)) + } + + /// Set the data as needed + pub(crate) fn set_cache_data(&self, user_data: &UserData) -> RedisResult<()> { + let mut con = self.redis.get_connection()?; + + redis::cmd("HSET") + .arg(user_data.id_to_redis()) + .arg(user_data) + .query(&mut con)?; + + con.set(user_data.name_to_redis(), user_data.id())?; + + self.update_cache_expiry(user_data) + } + + fn update_cache_expiry(&self, user_data: &UserData) -> RedisResult<()> { + let mut con = self.redis.get_connection()?; + con.expire(user_data.id_to_redis(), self.timeout)?; + con.expire(user_data.name_to_redis(), self.timeout)?; + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 3e55a65..83ed602 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,21 @@ use std::error::Error; -use redis::{Commands, RedisWrite, ToRedisArgs}; +use avatar_cache::AvatarCache; +use user_data::UserData; -#[derive(Debug)] -struct UserData { - name: String, - display_name: String, - id: String, - profile_picture_url: String, -} - -impl ToRedisArgs for UserData { - fn write_redis_args(&self, out: &mut W) where W: ?Sized + RedisWrite { - todo!() - } -} +mod user_data; +mod avatar_cache; fn main() -> Result<(), Box> { let client = redis::Client::open("redis://127.0.0.1/")?; - let cache = AvatarCache::new(client, 10); - - let data = cache.get_cache_by_name("TBSliver")?; - - dbg!(&data); - - cache.set_cache_data(data)?; - + let cache = AvatarCache::new(client, 60); + + let data = cache.get_cache_by_name("tbsliver").unwrap_or_else(|e| { + println!("Cache Miss for tbsliver"); + UserData::new("empty".to_string(), "empty".to_string(), "empty".to_string(), "empty".to_string()) + }); + + cache.set_cache_data(&data)?; + Ok(()) } -struct AvatarCache { - redis: redis::Client, - timeout: i64, -} - -impl AvatarCache { - fn new(redis: redis::Client, timeout: i64) -> Self { - AvatarCache { - redis, - timeout, - } - } - - fn build_id_key (&self, user_data: &UserData) -> String { - format!("twitchId:{}", user_data.id) - } - - fn build_name_key (&self, user_data: &UserData) -> String { - format!("twitchName:{}", user_data.name) - } - - /// Get user data from Cache - fn get_cache_by_name(&self, name: &str) -> Result> { - Ok(UserData { - name: "".to_string(), - display_name: "".to_string(), - id: "".to_string(), - profile_picture_url: "".to_string(), - }) - } - - /// Set the data as needed for - fn set_cache_data(&self, user_data: UserData) -> Result<(), Box> { - let mut con = self.redis.get_connection()?; - - con.hset(self.build_id_key(&user_data), &user_data)?; - con.expire(self.build_id_key(&user_data), self.timeout)?; - - con.set(self.build_name_key(&user_data), &user_data.id)?; - con.expire(self.build_name_key(&user_data), self.timeout)?; - - Ok(()) - } -} diff --git a/src/user_data.rs b/src/user_data.rs new file mode 100644 index 0000000..3bb53d3 --- /dev/null +++ b/src/user_data.rs @@ -0,0 +1,39 @@ +use redis_derive::{FromRedisValue, ToRedisArgs}; + +#[derive(Debug, ToRedisArgs, FromRedisValue)] +pub struct UserData { + name: String, + display_name: String, + id: String, + profile_picture_url: String, +} + +impl UserData { + pub fn new(name: String, display_name: String, id: String, profile_picture_url: String) -> Self { + UserData { + name, + display_name, + id, + profile_picture_url + } + } + pub fn redis_id_from_str(name: &str) -> String { + format!("twitchId:{}", name) + } + + pub fn redis_name_from_str(name: &str) -> String { + format!("twitchName:{}", name) + } + + pub fn id_to_redis(&self) -> String { + Self::redis_id_from_str(&self.id) + } + + pub fn name_to_redis(&self) -> String { + Self::redis_name_from_str(&self.name) + } + + pub fn id(&self) -> String { + self.id.to_string() + } +}