diff options
Diffstat (limited to 'src/cache')
| -rw-r--r-- | src/cache/cache_update.rs | 100 | ||||
| -rw-r--r-- | src/cache/mod.rs | 22 |
2 files changed, 118 insertions, 4 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>; } diff --git a/src/cache/mod.rs b/src/cache/mod.rs index e0a5ee6..3bf5a5a 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -56,7 +56,7 @@ use std::{ mod cache_update; -pub(crate) use self::cache_update::*; +pub use self::cache_update::CacheUpdate; /// A cache of all events received over a [`Shard`], where storing at least /// some data from the event is possible. @@ -163,6 +163,12 @@ pub struct Cache { } impl Cache { + /// Creates a new cache. + #[inline] + pub fn new() -> Self { + Self::default() + } + /// Fetches the number of [`Member`]s that have not had data received. /// /// The important detail to note here is that this is the number of @@ -664,8 +670,18 @@ impl Cache { self.categories.get(&channel_id).cloned() } - #[cfg(feature = "client")] - pub(crate) fn update<E: CacheUpdate>(&mut self, e: &mut E) -> Option<E::Output> { + /// Updates the cache with the update implementation for an event or other + /// custom update implementation. + /// + /// Refer to the documentation for [`CacheUpdate`] for more information. + /// + /// # Examples + /// + /// Refer to the [`CacheUpdate` examples]. + /// + /// [`CacheUpdate`]: trait.CacheUpdate.html + /// [`CacheUpdate` examples]: trait.CacheUpdate.html#examples + pub fn update<E: CacheUpdate>(&mut self, e: &mut E) -> Option<E::Output> { e.update(self) } |