signer-daemon 0.3.1

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) -> anyhow::Result<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) -> anyhow::Result<()> {
    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,
  ) -> anyhow::Result<()> {
    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,
  ) -> anyhow::Result<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,
  ) -> anyhow::Result<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)
  }
}