signer-daemon 0.3.1

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