signer-crdt 0.4.1

Signer CRDT (Conflict-free Replicated Data Type) package.
Documentation
use serde::{Deserialize, Serialize};

use super::deltaobject::DeltaField;
use crate::{view::ChatVO, DeltaError, SignerMeta};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatDO {
    pub chat_key: String,
    pub chat_variant: String,
    pub view_object: DeltaField<ChatVO>,
}

impl ChatDO {
    pub async fn from_vo(meta: &SignerMeta, vo: ChatVO) -> Result<Self, DeltaError> {
        Ok(Self {
            chat_key: vo.chat_key(meta).await?,
            chat_variant: vo.chat_variant(),
            view_object: DeltaField::Set(vo),
        })
    }

    pub async fn new(
        meta: &SignerMeta,
        from: &ChatVO,
        to: &ChatVO,
    ) -> Result<Self, DeltaError> {
        let from_chat_key = from.chat_key(meta).await?;
        let to_chat_key = to.chat_key(meta).await?;

        if from_chat_key != to_chat_key {
            return Err(DeltaError::InvalidParamsError(
                "ChatDO 对象中 chat_key 不一致".to_string(),
            ));
        }

        let from_chat_variant = from.chat_variant();
        let to_chat_variant = to.chat_variant();
        if from_chat_variant != to_chat_variant {
            return Err(DeltaError::InvalidParamsError(
                "ChatDO 对象中 chat_variant 不一致".to_string(),
            ));
        }

        Ok(Self {
            chat_key: from_chat_key,
            chat_variant: from_chat_variant,
            view_object: DeltaField::new(&from, &to),
        })
    }

    pub fn has_changed(&self, vo: &ChatVO) -> bool {
        if let DeltaField::Set(val) = &self.view_object {
            if *val != *vo {
                return true;
            }
        }
        false
    }
}