use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use super::super::identifier;
use crate::serve::protocol::DocumentDeleteMany;
use crate::serve::storage::Failure;
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "kind", deny_unknown_fields)]
pub enum Deletion {
#[serde(rename = "document.delete")]
Document {
collection: String,
document_id: String,
},
}
pub(super) fn entries(delete: &DocumentDeleteMany) -> Vec<Deletion> {
delete
.document_ids
.iter()
.map(|id| Deletion::Document {
collection: delete.collection.clone(),
document_id: id.clone(),
})
.collect()
}
pub(super) fn validate(entries: &[Deletion]) -> Result<(), Failure> {
if entries.is_empty() {
return Err(Failure::new(
"change_record_count",
"an accepted delete batch cannot be empty",
));
}
let mut identities = BTreeSet::new();
let mut collection = None;
for Deletion::Document {
collection: name,
document_id,
} in entries
{
identifier(name)?;
identifier(document_id)?;
if collection.is_some_and(|previous| previous != name) {
return Err(Failure::new(
"change_record_collection",
"a delete batch names one collection",
));
}
collection = Some(name);
if !identities.insert(document_id) {
return Err(Failure::new(
"change_record_duplicate",
"duplicate deletion attribution",
));
}
}
Ok(())
}