diff options
| author | zeyla <[email protected]> | 2018-07-05 09:26:46 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2018-07-05 09:26:46 -0700 |
| commit | 9e560628deb1cf66e0c5029f41a79404fadffb40 (patch) | |
| tree | 83b28db08fd1c26fdfd577334252c2b6c618fcf7 /src/cache/cache_update.rs | |
| parent | Monomorphize all functions (diff) | |
| download | serenity-9e560628deb1cf66e0c5029f41a79404fadffb40.tar.xz serenity-9e560628deb1cf66e0c5029f41a79404fadffb40.zip | |
Make the Cache Update API public (#344)
This commit makes the Cache Update API public, allowing users to manually update
the cache, as well as implementing the caching API on their own types to work
with mutating the cache.
The motivation for this indirectly comes from a message cache: if a user has
multiple processes that can receive cache updates (either splitting a bot's
shards into multiple processes or other processes like web panels or pub/sub
channels), then this will allow them to easily mutate the cache and feed all
types implementing the CacheUpdate trait into `Cache::update`.
Diffstat (limited to 'src/cache/cache_update.rs')
| -rw-r--r-- | src/cache/cache_update.rs | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/src/cache/cache_update.rs b/src/cache/cache_update.rs index a05cc3d..ba79727 100644 --- a/src/cache/cache_update.rs +++ b/src/cache/cache_update.rs @@ -1,7 +1,105 @@ use super::Cache; -pub(crate) trait CacheUpdate { +/// Trait used for updating the cache with a type. +/// +/// This may be implemented on a type and used to update the cache via +/// [`Cache::update`]. +/// +/// # Examples +/// +/// Creating a custom struct implementation to update the cache with: +/// +/// ```rust +/// use serenity::{ +/// cache::{Cache, CacheUpdate}, +/// model::{ +/// id::UserId, +/// user::User, +/// }, +/// prelude::RwLock, +/// }; +/// use std::{ +/// collections::hash_map::Entry, +/// sync::Arc, +/// }; +/// +/// // For example, an update to the user's record in the database was +/// // published to a pubsub channel. +/// struct DatabaseUserUpdate { +/// user_avatar: Option<String>, +/// user_discriminator: u16, +/// user_id: UserId, +/// user_is_bot: bool, +/// user_name: String, +/// } +/// +/// impl CacheUpdate for DatabaseUserUpdate { +/// // A copy of the old user's data, if it existed in the cache. +/// type Output = User; +/// +/// fn update(&mut self, cache: &mut Cache) -> Option<Self::Output> { +/// // If an entry for the user already exists, update its fields. +/// match cache.users.entry(self.user_id) { +/// Entry::Occupied(entry) => { +/// let user = entry.get(); +/// let mut writer = user.write(); +/// let old = writer.clone(); +/// +/// writer.bot = self.user_is_bot; +/// writer.discriminator = self.user_discriminator; +/// writer.id = self.user_id; +/// +/// if writer.avatar != self.user_avatar { +/// writer.avatar = self.user_avatar.clone(); +/// } +/// +/// if writer.name != self.user_name { +/// writer.name = self.user_name.clone(); +/// } +/// +/// // Return the old copy for the user's sake. +/// Some(old) +/// }, +/// Entry::Vacant(entry) => { +/// entry.insert(Arc::new(RwLock::new(User { +/// id: self.user_id, +/// avatar: self.user_avatar.clone(), +/// bot: self.user_is_bot, +/// discriminator: self.user_discriminator, +/// name: self.user_name.clone(), +/// }))); +/// +/// // There was no old copy, so return None. +/// None +/// }, +/// } +/// } +/// } +/// +/// // Create an instance of the cache. +/// let mut cache = Cache::new(); +/// +/// // This is a sample pubsub message that you might receive from your +/// // database. +/// let mut update_message = DatabaseUserUpdate { +/// user_avatar: None, +/// user_discriminator: 6082, +/// user_id: UserId(379740138303127564), +/// user_is_bot: true, +/// user_name: "TofuBot".to_owned(), +/// }; +/// +/// // Update the cache with the message. +/// cache.update(&mut update_message); +/// ``` +/// +/// [`Cache::update`]: struct.Cache.html#method.update +pub trait CacheUpdate { + /// The return type of an update. + /// + /// If there is nothing to return, specify this type as an unit (`()`). type Output; + /// Updates the cache with the implementation. fn update(&mut self, &mut Cache) -> Option<Self::Output>; } |