serenity/cache/
cache_update.rs

1use super::Cache;
2
3/// Trait used for updating the cache with a type.
4///
5/// This may be implemented on a type and used to update the cache via [`Cache::update`].
6///
7/// **Info**: You may not access the fields of the cache, as they are public for the crate only.
8///
9/// # Examples
10///
11/// Creating a custom struct implementation to update the cache with:
12///
13/// ```rust,ignore
14/// use std::collections::hash_map::Entry;
15///
16/// use serenity::json::json;
17/// use serenity::cache::{Cache, CacheUpdate};
18/// use serenity::model::id::UserId;
19/// use serenity::model::user::User;
20///
21/// // For example, an update to the user's record in the database was
22/// // published to a pubsub channel.
23/// struct DatabaseUserUpdate {
24///     user_avatar: Option<String>,
25///     user_discriminator: u16,
26///     user_id: UserId,
27///     user_is_bot: bool,
28///     user_name: String,
29/// }
30///
31/// #[serenity::async_trait]
32/// impl CacheUpdate for DatabaseUserUpdate {
33///     // A copy of the old user's data, if it existed in the cache.
34///     type Output = User;
35///
36///     async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
37///         // If an entry for the user already exists, update its fields.
38///         match cache.users.entry(self.user_id) {
39///             Entry::Occupied(entry) => {
40///                 let user = entry.get();
41///                 let old_user = user.clone();
42///
43///                 user.bot = self.user_is_bot;
44///                 user.discriminator = self.user_discriminator;
45///                 user.id = self.user_id;
46///
47///                 if user.avatar != self.user_avatar {
48///                     user.avatar = self.user_avatar.clone();
49///                 }
50///
51///                 if user.name != self.user_name {
52///                     user.name = self.user_name.clone();
53///                 }
54///
55///                 // Return the old copy for the user's sake.
56///                 Some(old_user)
57///             },
58///             Entry::Vacant(entry) => {
59///                 // We can convert a [`json::Value`] to a User for test
60///                 // purposes.
61///                 let user = from_value::<User>(json!({
62///                     "id": self.user_id,
63///                     "avatar": self.user_avatar.clone(),
64///                     "bot": self.user_is_bot,
65///                     "discriminator": self.user_discriminator,
66///                     "username": self.user_name.clone(),
67///                 })).expect("Error making user");
68///
69///                 entry.insert(user);
70///
71///                 // There was no old copy, so return None.
72///                 None
73///             },
74///         }
75///     }
76/// }
77///
78/// # async fn run() {
79/// // Create an instance of the cache.
80/// let mut cache = Cache::new();
81///
82/// // This is a sample pubsub message that you might receive from your
83/// // database.
84/// let mut update_message = DatabaseUserUpdate {
85///     user_avatar: None,
86///     user_discriminator: 6082,
87///     user_id: UserId::new(379740138303127564),
88///     user_is_bot: true,
89///     user_name: "TofuBot".to_owned(),
90/// };
91///
92/// // Update the cache with the message.
93/// cache.update(&mut update_message).await;
94/// # }
95/// ```
96pub trait CacheUpdate {
97    /// The return type of an update.
98    ///
99    /// If there is nothing to return, specify this type as an unit (`()`).
100    type Output;
101
102    /// Updates the cache with the implementation.
103    fn update(&mut self, _: &Cache) -> Option<Self::Output>;
104}