53 lines
1.5 KiB
Rust
53 lines
1.5 KiB
Rust
use crate::error::RealtimeError;
|
|
use async_trait::async_trait;
|
|
|
|
use collab::core::collab::DataSource;
|
|
use collab::core::collab_plugin::EncodedCollab;
|
|
use collab::core::origin::CollabOrigin;
|
|
use collab::preclude::Collab;
|
|
use collab_entity::CollabType;
|
|
use database_entity::dto::CollabParams;
|
|
use tracing::instrument;
|
|
|
|
#[async_trait]
|
|
pub trait CollabValidator {
|
|
async fn check_encode_collab(&self) -> Result<(), RealtimeError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
impl CollabValidator for CollabParams {
|
|
async fn check_encode_collab(&self) -> Result<(), RealtimeError> {
|
|
validate_encode_collab(&self.object_id, &self.encoded_collab_v1, &self.collab_type).await
|
|
}
|
|
}
|
|
|
|
#[instrument(level = "trace", skip(data), fields(len = %data.len()))]
|
|
pub async fn validate_encode_collab(
|
|
object_id: &str,
|
|
data: &[u8],
|
|
collab_type: &CollabType,
|
|
) -> Result<(), RealtimeError> {
|
|
let collab_type = collab_type.clone();
|
|
let object_id = object_id.to_string();
|
|
let data = data.to_vec();
|
|
|
|
tokio::task::spawn_blocking(move || {
|
|
let encoded_collab =
|
|
EncodedCollab::decode_from_bytes(&data).map_err(|err| RealtimeError::Internal(err.into()))?;
|
|
let collab = Collab::new_with_source(
|
|
CollabOrigin::Empty,
|
|
&object_id,
|
|
DataSource::DocStateV1(encoded_collab.doc_state.to_vec()),
|
|
vec![],
|
|
false,
|
|
)
|
|
.map_err(|err| RealtimeError::Internal(err.into()))?;
|
|
|
|
collab_type
|
|
.validate(&collab)
|
|
.map_err(|err| RealtimeError::NoRequiredCollabData(err.to_string()))?;
|
|
Ok::<(), RealtimeError>(())
|
|
})
|
|
.await?
|
|
}
|