tetratto-core 16.0.1

The core behind Tetratto
Documentation
use std::collections::HashMap;

use serde::{Serialize, Deserialize};
use tetratto_shared::{snow::Snowflake, unix_epoch_timestamp};

use super::communities_permissions::CommunityPermission;

/// A channel is a more "chat-like" feed in communities.
#[derive(Clone, Serialize, Deserialize)]
pub struct Channel {
    pub id: usize,
    pub community: usize,
    pub owner: usize,
    pub created: usize,
    /// The minimum role (as bits) that can read this channel.
    pub minimum_role_read: u32,
    /// The minimum role (as bits) that can write to this channel.
    pub minimum_role_write: u32,
    /// The position of this channel in the UI.
    ///
    /// Top (0) to bottom.
    pub position: usize,
    /// The members of the chat (ids). Should be empty if `community > 0`.
    ///
    /// The owner should not be a member of the channel since any member can update members.
    pub members: Vec<usize>,
    /// The title of the channel.
    pub title: String,
    /// The timestamp of the last message in the channel.
    pub last_message: usize,
}

impl Channel {
    /// Create a new [`Channel`].
    pub fn new(community: usize, owner: usize, position: usize, title: String) -> Self {
        let created = unix_epoch_timestamp();

        Self {
            id: Snowflake::new().to_string().parse::<usize>().unwrap(),
            community,
            owner,
            created,
            minimum_role_read: (CommunityPermission::DEFAULT | CommunityPermission::MEMBER).bits(),
            minimum_role_write: (CommunityPermission::DEFAULT | CommunityPermission::MEMBER).bits(),
            position,
            members: Vec::new(),
            title,
            last_message: created,
        }
    }

    /// Check if the given `uid` can post in the channel.
    pub fn check_post(&self, uid: usize, membership: Option<CommunityPermission>) -> bool {
        let mut is_member = false;

        if let Some(membership) = membership {
            is_member = membership.bits() >= self.minimum_role_write
        }

        (uid == self.owner) | is_member | self.members.contains(&uid)
    }

    /// Check if the given `uid` can post in the channel.
    pub fn check_read(&self, uid: usize, membership: Option<CommunityPermission>) -> bool {
        let mut is_member = false;

        if let Some(membership) = membership {
            is_member = membership.bits() >= self.minimum_role_read
        }

        (uid == self.owner) | is_member | self.members.contains(&uid)
    }
}

#[derive(Clone, Serialize, Deserialize)]
pub struct Message {
    pub id: usize,
    pub channel: usize,
    pub owner: usize,
    pub created: usize,
    pub edited: usize,
    pub content: String,
    pub context: MessageContext,
    pub reactions: HashMap<String, usize>,
}

impl Message {
    pub fn new(channel: usize, owner: usize, content: String) -> Self {
        let now = unix_epoch_timestamp();

        Self {
            id: Snowflake::new().to_string().parse::<usize>().unwrap(),
            channel,
            owner,
            created: now,
            edited: now,
            content,
            context: MessageContext,
            reactions: HashMap::new(),
        }
    }
}

#[derive(Clone, Serialize, Deserialize)]
pub struct MessageContext;

impl Default for MessageContext {
    fn default() -> Self {
        Self
    }
}

#[derive(Clone, Serialize, Deserialize)]
pub struct MessageReaction {
    pub id: usize,
    pub created: usize,
    pub owner: usize,
    pub message: usize,
    pub emoji: String,
}

impl MessageReaction {
    /// Create a new [`MessageReaction`].
    pub fn new(owner: usize, message: usize, emoji: String) -> Self {
        Self {
            id: Snowflake::new().to_string().parse::<usize>().unwrap(),
            created: unix_epoch_timestamp(),
            owner,
            message,
            emoji,
        }
    }
}