signer-daemon 0.3.2

Signer daemon package.
Documentation
use crate::{
    CrdtAdapterController, CrdtEventController, SignerDaemonCore,
    entity::{chat, message},
    model::{
        crdt::crdt::{CrdtDelta, CrdtDeltaBox},
        deltaobject::chat_do::ChatDO,
        viewobject::{ChatVO, MessageContent, MessageKeyVO, MessageVO, Null},
    },
};
use sea_orm::{QueryOrder, prelude::*};

pub struct ChatStore {
    core: SignerDaemonCore,
    crdt_event: CrdtEventController,
    crdt_adapter: CrdtAdapterController,
}

impl ChatStore {
    pub fn new(core: SignerDaemonCore) -> Self {
        Self {
            core: core.clone(),
            crdt_event: CrdtEventController::new(core.clone()),
            crdt_adapter: CrdtAdapterController::new(core.clone()),
        }
    }

    pub async fn list(&self) -> crate::DaemonResult<Vec<ChatVO>> {
        let r = chat::Entity::find().all(&self.core.db).await?;
        let mut chats = Vec::new();
        for i in r {
            chats.push(serde_json::from_str(&i.view_object)?);
        }
        Ok(chats)
    }

    pub async fn put(&mut self, vo: ChatVO) -> crate::DaemonResult<()> {
        let r = chat::Entity::find()
            .filter(
                chat::Column::ChatKey
                    .eq(&vo.chat_key(&self.core).await?)
                    .and(chat::Column::ChatVariant.eq(&vo.chat_variant())),
            )
            .one(&self.core.db)
            .await?;
        let chat_do = match &r {
            Some(val) => {
                let chat_do =
                    ChatDO::new(&self.core, &serde_json::from_str(&val.view_object)?, &vo).await?;
                if !chat_do.has_changed(&vo) {
                    return Ok(());
                }
                chat_do
            }
            None => ChatDO::from_vo(&self.core, vo.clone()).await?,
        };

        let delta = CrdtDeltaBox::Chat(CrdtDelta::Put(chat_do));
        self.crdt_event.insert_delta(delta.clone()).await?;
        self.crdt_adapter.apply_all().await?;

        self.core.change_notifier.notify(delta);

        Ok(())
    }

    pub async fn del(&mut self, chat_key: &str, chat_variant: &str) -> crate::DaemonResult<()> {
        if self.get(chat_key, chat_variant).await?.is_none() {
            return Ok(());
        }

        let delta = CrdtDeltaBox::Chat(CrdtDelta::Del((
            chat_key.to_string(),
            chat_variant.to_string(),
        )));
        self.crdt_event.insert_delta(delta.clone()).await?;
        self.crdt_adapter.apply_all().await?;

        self.core.change_notifier.notify(delta);

        Ok(())
    }

    pub async fn get(
        &self,
        chat_key: &str,
        chat_variant: &str,
    ) -> crate::DaemonResult<Option<ChatVO>> {
        let r = chat::Entity::find()
            .filter(
                chat::Column::ChatKey
                    .eq(chat_key)
                    .and(chat::Column::ChatVariant.eq(chat_variant)),
            )
            .one(&self.core.db)
            .await?;
        Ok(r.map(|i| serde_json::from_str(&i.view_object).expect("serialize view object failed")))
    }

    pub async fn list_message_key(
        &self,
        chat_key: &str,
        chat_variant: &str,
    ) -> crate::DaemonResult<Vec<MessageKeyVO>> {
        let records = message::Entity::find()
            .filter(
                message::Column::ChatKey
                    .eq(chat_key)
                    .and(message::Column::ChatVariant.eq(chat_variant))
                    .and(message::Column::ContentType.ne(MessageContent::Check(Null {}).ty())),
            )
            .order_by_asc(message::Column::CreateTime)
            .all(&self.core.db)
            .await?;

        let mut message_keys = Vec::new();
        for record in records {
            let message_vo = MessageVO::from_model(&self.core.db, &record).await?;
            message_keys.push(MessageKeyVO::from_message(&self.core, &message_vo).await?);
        }

        Ok(message_keys)
    }
}