signer-daemon 0.3.2

Signer daemon package.
Documentation
use crate::{
    ChatStore, CrdtAdapterController, CrdtEventController, SignerDaemonCore,
    entity::message,
    model::{
        crdt::{
            crdt::{CrdtDelta, CrdtDeltaBox},
            crdt_message::MessageKey,
        },
        deltaobject::message_do::MessageDO,
        viewobject::{MessageContent, MessageVO, Null},
    },
};
use sea_orm::prelude::*;

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

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

    pub async fn list(&self) -> crate::DaemonResult<Vec<MessageVO>> {
        let r = message::Entity::find().all(&self.core.db).await?;
        let mut messages = Vec::new();
        for i in r {
            messages.push(MessageVO::from_model(&self.core.db, &i).await?);
        }
        Ok(messages)
    }

    pub async fn put(&mut self, vo: MessageVO) -> crate::DaemonResult<()> {
        self.chat_store.put(vo.chat.clone()).await?;

        let r = message::Entity::find()
            .filter(
                message::Column::Id.eq(&vo.id).and(
                    message::Column::UserKey
                        .eq(&vo.user_key)
                        .and(message::Column::ChatKey.eq(&vo.chat.chat_key(&self.core).await?))
                        .and(message::Column::ChatVariant.eq(&vo.chat.chat_variant())),
                ),
            )
            .one(&self.core.db)
            .await?;

        let message_do = match &r {
            Some(val) => {
                let message_do =
                    MessageDO::new(&MessageVO::from_model(&self.core.db, &val).await?, &vo)?;
                if !message_do.has_changed(&vo) {
                    return Ok(());
                }
                message_do
            }
            None => MessageDO::from(vo.clone()),
        };

        let delta = CrdtDeltaBox::Message(CrdtDelta::Put(message_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,
        id: &str,
        user_key: &str,
        chat_key: &str,
        chat_variant: &str,
    ) -> crate::DaemonResult<()> {
        if self
            .get(id, user_key, chat_key, chat_variant)
            .await?
            .is_none()
        {
            return Ok(());
        }

        let delta = CrdtDeltaBox::Message(CrdtDelta::Del(MessageKey {
            id: id.to_string(),
            user_key: user_key.to_string(),
            chat_key: chat_key.to_string(),
            chat_variant: 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,
        id: &str,
        user_key: &str,
        chat_key: &str,
        chat_variant: &str,
    ) -> crate::DaemonResult<Option<MessageVO>> {
        let r = message::Entity::find()
            .filter(
                message::Column::Id.eq(id).and(
                    message::Column::UserKey
                        .eq(user_key)
                        .and(message::Column::ChatKey.eq(chat_key))
                        .and(message::Column::ChatVariant.eq(chat_variant)),
                ),
            )
            .one(&self.core.db)
            .await?;

        let m = match &r {
            None => None,
            Some(val) => Some(MessageVO::from_model(&self.core.db, val).await?),
        };

        Ok(m)
    }

    pub async fn list_checked(
        &self,
        id: &str,
        user_key: &str,
        chat_key: &str,
        chat_variant: &str,
    ) -> crate::DaemonResult<Vec<MessageVO>> {
        let r = message::Entity::find()
            .filter(
                message::Column::ParentId
                    .eq(id)
                    .and(message::Column::ParentUserKey.eq(user_key))
                    .and(message::Column::ChatKey.eq(chat_key))
                    .and(message::Column::ChatVariant.eq(chat_variant))
                    .and(
                        message::Column::Content
                            .eq(serde_json::to_string(&MessageContent::Check(Null {}))?),
                    ),
            )
            .all(&self.core.db)
            .await?;

        let mut messages = Vec::new();
        for i in r {
            messages.push(MessageVO::from_model(&self.core.db, &i).await?);
        }

        Ok(messages)
    }
}