zynko 0.1.0

Biblioteca oficial para bots do Zynko: API, gateway e voz.
Documentation
//! What the client keeps, updated by the gateway's events.

use std::collections::{HashMap, HashSet};

use crate::types::*;

/// A server as the client keeps it.
#[derive(Debug, Clone, Default)]
pub struct CachedGuild {
    pub id: Id,
    pub name: String,
    pub icon: Option<String>,
    pub owner_id: Id,
    pub channels: HashMap<Id, Channel>,
    pub members: HashMap<Id, Member>,
    pub roles: HashMap<Id, Role>,
    pub emojis: Vec<Emoji>,
    /// Ids of members online now (needs the PRESENCES intent to stay current).
    pub online: HashSet<Id>,
}

impl From<GuildFull> for CachedGuild {
    fn from(g: GuildFull) -> Self {
        Self {
            id: g.id,
            name: g.name,
            icon: g.icon,
            owner_id: g.owner_id,
            channels: g.channels.into_iter().map(|c| (c.id.clone(), c)).collect(),
            members: g
                .members
                .into_iter()
                .map(|m| (m.user.id.clone(), m))
                .collect(),
            roles: g.roles.into_iter().map(|r| (r.id.clone(), r)).collect(),
            emojis: g.emojis,
            online: g.presences.into_iter().collect(),
        }
    }
}

/// Everything the client knows. Read it with [`Client::cache`](crate::Client::cache); the
/// gateway's events keep it current.
#[derive(Debug, Default)]
pub struct Cache {
    /// The bot's account, after READY.
    pub user: Option<User>,
    pub session_id: String,
    pub guilds: HashMap<Id, CachedGuild>,
    /// Every channel the bot sees, DMs included.
    pub channels: HashMap<Id, Channel>,
    /// Accounts the bot has seen.
    pub users: HashMap<Id, User>,
    /// Who is in voice, by user id (needs VOICE_STATES).
    pub voice_states: HashMap<Id, VoiceState>,
}

impl Cache {
    pub(crate) fn add_guild(&mut self, g: GuildFull) -> CachedGuild {
        let cached = CachedGuild::from(g);
        for c in cached.channels.values() {
            self.channels.insert(c.id.clone(), c.clone());
        }
        for m in cached.members.values() {
            self.users.insert(m.user.id.clone(), m.user.clone());
        }
        self.guilds.insert(cached.id.clone(), cached.clone());
        cached
    }

    pub(crate) fn drop_guild(&mut self, id: &str) {
        if let Some(g) = self.guilds.remove(id) {
            for c in g.channels.keys() {
                self.channels.remove(c);
            }
        }
    }
}