signer-crdt 0.4.1

Signer CRDT (Conflict-free Replicated Data Type) package.
Documentation
use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseTransaction, EntityTrait};

use crate::{
    SignerMeta, crdt::errors::CrdtError, delta::user_do::UserDO, entity::user, view::UserVO,
};

use super::{CrdtType, crdt::CrdtDelta};

impl CrdtType for UserDO {
    type PrimaryKey = String;

    async fn put(
        &self,
        _core: &SignerMeta,
        tx: &DatabaseTransaction,
    ) -> Result<CrdtDelta<Self>, CrdtError> {
        let u = user::Entity::find_by_id(&self.pub_key).one(tx).await?;
        if let Some(val) = &u {
            if !self.has_changed(&val.clone().into()) {
                return Ok(CrdtDelta::Skip);
            }
        }

        let m = user::ActiveModel {
            pub_key: Set(self.pub_key.clone()),
            user_public: self.user_public.clone().into(),
            signed_user_public: self.signed_user_public.clone().into(),
        };

        match u {
            Some(val) => {
                let m = m.update(tx).await?;
                let user_do = UserDO::new(&m.into(), &val.into())?;
                Ok(CrdtDelta::Put(user_do))
            }
            None => {
                let m = m.insert(tx).await?;
                Ok(CrdtDelta::Del(m.pub_key))
            }
        }
    }

    async fn del(
        _core: &SignerMeta,
        key: &String,
        tx: &DatabaseTransaction,
    ) -> Result<CrdtDelta<Self>, CrdtError> {
        let m = user::Entity::find_by_id(key).one(tx).await?;
        match m {
            Some(val) => {
                let user_do = UserDO::from(UserVO::from(val.clone()));
                user::Entity::delete_by_id(&val.pub_key).exec(tx).await?;

                Ok(CrdtDelta::Put(user_do))
            }
            None => Ok(CrdtDelta::Skip),
        }
    }
}