This commit is contained in:
Tom Bloor 2024-04-20 14:17:07 +01:00
parent e9b12a999c
commit abb999e3f2
Signed by: TBSliver
GPG key ID: 4657C7EBE42CC5CC
5 changed files with 383 additions and 67 deletions

286
Cargo.lock generated
View file

@ -2,6 +2,37 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "bytes" name = "bytes"
version = "1.6.0" version = "1.6.0"
@ -18,6 +49,23 @@ dependencies = [
"memchr", "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]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.1" version = "1.2.1"
@ -27,6 +75,23 @@ dependencies = [
"percent-encoding", "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]] [[package]]
name = "idna" name = "idna"
version = "0.5.0" version = "0.5.0"
@ -49,18 +114,69 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.1" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 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]] [[package]]
name = "redis" name = "redis"
version = "0.25.3" version = "0.25.3"
@ -76,11 +192,25 @@ dependencies = [
"url", "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]] [[package]]
name = "rust-twitch-avatar-cache" name = "rust-twitch-avatar-cache"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"redis", "redis 0.25.3",
"redis-derive",
"twitch_api",
] ]
[[package]] [[package]]
@ -89,6 +219,35 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 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]] [[package]]
name = "sha1_smol" name = "sha1_smol"
version = "1.0.0" version = "1.0.0"
@ -105,6 +264,48 @@ dependencies = [
"windows-sys", "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]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -120,12 +321,89 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 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]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.15" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.23" version = "0.1.23"
@ -146,6 +424,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"

View file

@ -7,3 +7,5 @@ edition = "2021"
[dependencies] [dependencies]
redis = "0.25.3" redis = "0.25.3"
redis-derive = "0.1.7"
twitch_api = "0.7.0-rc.7"

44
src/avatar_cache.rs Normal file
View file

@ -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<UserData> {
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(())
}
}

View file

@ -1,74 +1,21 @@
use std::error::Error; use std::error::Error;
use redis::{Commands, RedisWrite, ToRedisArgs}; use avatar_cache::AvatarCache;
use user_data::UserData;
#[derive(Debug)] mod user_data;
struct UserData { mod avatar_cache;
name: String,
display_name: String,
id: String,
profile_picture_url: String,
}
impl ToRedisArgs for UserData {
fn write_redis_args<W>(&self, out: &mut W) where W: ?Sized + RedisWrite {
todo!()
}
}
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let client = redis::Client::open("redis://127.0.0.1/")?; let client = redis::Client::open("redis://127.0.0.1/")?;
let cache = AvatarCache::new(client, 10); let cache = AvatarCache::new(client, 60);
let data = cache.get_cache_by_name("TBSliver")?; 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())
});
dbg!(&data); cache.set_cache_data(&data)?;
cache.set_cache_data(data)?;
Ok(()) 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<UserData, Box<dyn Error>> {
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<dyn Error>> {
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(())
}
}

39
src/user_data.rs Normal file
View file

@ -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()
}
}