signer-daemon 0.3.2

Signer daemon package.
Documentation
use sea_orm::{ColumnTrait, ConnectionTrait, EntityTrait, QueryFilter};
use serde::{Deserialize, Serialize};

use crate::{
    SignerDaemon, SignerDaemonCore,
    entity::{chat, message},
    model::viewobject::Null,
};

use super::ChatVO;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "poem-openapi", derive(poem_openapi::Object))]
pub struct MessageVO {
    pub chat: ChatVO,
    pub id: String,
    pub user_key: String,
    pub parent_id: Option<String>,
    pub parent_user_key: Option<String>,
    pub content: MessageContent,
    pub receiver_keys: Vec<String>,
    pub create_time: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "poem-openapi", derive(poem_openapi::Union))]
pub enum MessageContent {
    // 文本内容
    Text(String),
    // 图像链接
    Image(String),
    // 视频链接
    Video(String),
    // 文件链接
    File(String),
    // 已读
    Check(Null),
}

impl MessageVO {
    pub async fn create(
        core: &SignerDaemonCore,
        chat_vo: &ChatVO,
        content: &MessageContent,
    ) -> crate::DaemonResult<Self> {
        Ok(Self {
            chat: chat_vo.clone(),
            id: uuid::Uuid::new_v4().to_string(),
            parent_id: None,
            parent_user_key: None,
            content: content.clone(),
            user_key: core.pub_key.clone(),
            receiver_keys: chat_vo.receiver_keys(&core).await?,
            create_time: chrono::Utc::now().timestamp_millis(),
        })
    }

    pub async fn from_model(
        c: &impl ConnectionTrait,
        model: &message::Model,
    ) -> crate::DaemonResult<Self> {
        let chat_model = chat::Entity::find()
            .filter(
                chat::Column::ChatKey
                    .eq(&model.chat_key)
                    .and(chat::Column::ChatVariant.eq(&model.chat_variant)),
            )
            .one(c)
            .await?
            .expect("chat not found");
        let chat_vo = serde_json::from_str(&chat_model.view_object)?;

        Ok(Self {
            chat: chat_vo,
            id: model.id.clone(),
            parent_id: model.parent_id.clone(),
            parent_user_key: model.parent_user_key.clone(),
            content: serde_json::from_str(&model.content)?,
            user_key: model.user_key.clone(),
            receiver_keys: model
                .receiver_keys
                .split(',')
                .map(|s| s.to_string())
                .collect(),
            create_time: model.create_time.and_utc().timestamp_millis(),
        })
    }

    pub async fn create_check_message(
        &self,
        daemon: &SignerDaemon,
    ) -> crate::DaemonResult<MessageVO> {
        let user = daemon.state.user.clone();

        let message = MessageVO {
            chat: self.chat.clone(),
            id: uuid::Uuid::new_v4().to_string(),
            parent_id: Some(self.id.clone()),
            parent_user_key: Some(self.user_key.clone()),
            content: MessageContent::Check(Null {}),
            user_key: user.public.pub_key.clone(),
            receiver_keys: vec![],
            create_time: chrono::Utc::now().timestamp_millis(),
        };

        Ok(message)
    }
}

impl MessageContent {
    pub fn ty(&self) -> String {
        match self {
            MessageContent::Text(_) => "text".to_string(),
            MessageContent::Image(_) => "image".to_string(),
            MessageContent::Video(_) => "video".to_string(),
            MessageContent::File(_) => "file".to_string(),
            MessageContent::Check(_) => "check".to_string(),
        }
    }
}