Skip to content

Instantly share code, notes, and snippets.

@SpencerSharkey
Created September 13, 2020 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpencerSharkey/2e7d767bada7e70216ae710e6c8d782f to your computer and use it in GitHub Desktop.
Save SpencerSharkey/2e7d767bada7e70216ae710e6c8d782f to your computer and use it in GitHub Desktop.
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