aboutsummaryrefslogtreecommitdiff
path: root/src/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache')
-rw-r--r--src/cache/cache_update.rs100
-rw-r--r--src/cache/mod.rs22
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)
}