Created
September 13, 2020 09:37
-
-
Save SpencerSharkey/2e7d767bada7e70216ae710e6c8d782f to your computer and use it in GitHub Desktop.
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::collections::HashMap; | |
use std::hash::Hash; | |
// Snowflakes | |
#[derive(Eq, PartialEq, Hash)] | |
pub struct Snowflake(pub u64); | |
impl From<u64> for Snowflake { | |
fn from(item: u64) -> Self { | |
Self(item) | |
} | |
} | |
#[derive(Eq, PartialEq, Hash)] | |
pub struct GuildId(Snowflake); | |
impl<T: Into<Snowflake>> From<T> for GuildId { | |
fn from(item: T) -> Self { | |
Self(item.into()) | |
} | |
} | |
#[derive(Eq, PartialEq, Hash)] | |
pub struct UserId(Snowflake); | |
impl<T: Into<Snowflake>> From<T> for UserId { | |
fn from(item: T) -> Self { | |
Self(item.into()) | |
} | |
} | |
// Data | |
#[derive(Debug)] | |
pub struct GuildData { | |
pub name: String | |
} | |
pub struct UserData; | |
// Cache | |
pub struct Cache { | |
pub guilds: HashMap<GuildId, GuildData>, | |
pub users: HashMap<UserId, UserData>, | |
} | |
impl Cache { | |
pub fn new() -> Self { | |
Self { | |
guilds: Default::default(), | |
users: Default::default(), | |
} | |
} | |
} | |
// Impl for cache objects | |
pub trait CacheObject<'a, T: 'a + Eq + Hash + From<Snowflake>, R: 'a> { | |
fn object_map_mut(&'a mut self) -> &'a mut HashMap<T, R>; | |
fn object_map(&'a self) -> &'a HashMap<T, R>; | |
fn get(&'a self, id: &T) -> Option<&'a R> { | |
self.object_map().get(id) | |
} | |
fn insert<I: Into<T>>(&'a mut self, id: I, data: R) -> Option<R> { | |
self.object_map_mut().insert(id.into(), data) | |
} | |
} | |
impl CacheObject<'_, GuildId, GuildData> for Cache { | |
fn object_map(&self) -> &HashMap<GuildId, GuildData> { | |
&self.guilds | |
} | |
fn object_map_mut(&mut self) -> &mut HashMap<GuildId, GuildData> { | |
&mut self.guilds | |
} | |
} | |
impl CacheObject<'_, UserId, UserData> for Cache { | |
fn object_map(&self) -> &HashMap<UserId, UserData> { | |
&self.users | |
} | |
fn object_map_mut(&mut self) -> &mut HashMap<UserId, UserData> { | |
&mut self.users | |
} | |
} | |
#[cfg(test)] | |
pub mod test { | |
use super::*; | |
#[test] | |
fn test_cache() { | |
let mut cache = Cache::new(); | |
let data = GuildData{ | |
name: String::from("big guild") | |
}; | |
// insert test data | |
cache.insert(123, data); | |
// get with typed id | |
assert_eq!(cache.get(&GuildId::from(123)).unwrap().name, "big guild"); | |
// replace entry | |
assert_eq!(cache.insert(123, GuildData{ | |
name: String::from("new guild") | |
}).unwrap().name, "big guild"); | |
assert_eq!(cache.get(&GuildId::from(123)).unwrap().name, "new guild"); | |
// try to find None | |
assert!(cache.get(&GuildId::from(1337)).is_none()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment