signer-daemon 0.3.1

Signer daemon package.
Documentation
use crate::{
  CrdtAdapterController, CrdtEventController, SignerDaemonCore,
  SignerDaemonOption, SignerDaemonState,
  entity::user,
  model::{
    crdt::crdt::{CrdtDelta, CrdtDeltaBox},
    deltaobject::user_do::UserDO,
    viewobject::UserVO,
  },
  signer_daemon::user_info_synchronizer::UserInfoSynchronizer,
};
use sea_orm::prelude::*;

pub struct UserStore {
  core: SignerDaemonCore,
  crdt_event: CrdtEventController,
  crdt_adapter: CrdtAdapterController,
  option: SignerDaemonOption,
}

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

  pub async fn list(&self) -> anyhow::Result<Vec<UserVO>> {
    let users = user::Entity::find().all(&self.core.db).await?;
    Ok(users.into_iter().map(|i| i.into()).collect())
  }

  pub async fn put(
    &mut self,
    state: &mut SignerDaemonState,
    user_vo: UserVO,
  ) -> anyhow::Result<()> {
    let e = user::Entity::find_by_id(&user_vo.pub_key)
      .one(&self.core.db)
      .await?;

    let user_do = match &e {
      None => UserDO::from(user_vo.clone()),
      Some(e) => {
        let db_vo = UserVO::from(e.clone());
        let user_do = UserDO::new(&db_vo, &user_vo)?;
        if !user_do.has_changed(&db_vo) {  // 使用数据库中的数据进行比较
          return Ok(());
        }
        user_do
      }
    };

    let user_delta = CrdtDeltaBox::User(CrdtDelta::Put(user_do));
    self.crdt_event.insert_delta(user_delta.clone()).await?;
    self.crdt_adapter.apply_all().await?;

    let mut syncer =
      UserInfoSynchronizer::new(self.core.clone(), self.option.clone());
    Box::pin(syncer.sync(state)).await?;
    
    self.core.change_notifier.notify(user_delta);

    Ok(())
  }

  pub async fn del(&mut self, pub_key: &str) -> anyhow::Result<()> {
    if self.get(pub_key).await?.is_none() {
      return Ok(());
    }

    let user_delta = CrdtDeltaBox::User(CrdtDelta::Del(pub_key.to_string()));
    self.crdt_event.insert_delta(user_delta.clone()).await?;
    self.crdt_adapter.apply_all().await?;

    self.core.change_notifier.notify(user_delta);

    Ok(())
  }

  pub async fn get(&self, pub_key: &str) -> anyhow::Result<Option<UserVO>> {
    let u = user::Entity::find_by_id(pub_key).one(&self.core.db).await?;

    Ok(u.map(|i| i.into()))
  }
}