use crate::storage::Error;
use oauth2_client::re_exports::{Deserialize, Serialize};
use pbbson::{Model, prost::Message};
pub fn is_audit_field(key: &str) -> bool {
key.starts_with("created") || key.starts_with("deleted") || key.starts_with("updated")
}
pub fn is_equal_ignoring_audit_fields(left: &Model, right: &Model) -> bool {
for key in left.keys() {
if is_audit_field(key) {
continue;
}
if left.get(key) != right.get(key) {
return false;
}
}
for key in right.keys() {
if is_audit_field(key) {
continue;
}
if left.get(key) != right.get(key) {
return false;
}
}
true
}
pub fn is_message_equal_ignoring_audit_fields<T: Message + Clone + Default + for<'a> Deserialize<'a> + Serialize>(
left: &T,
right: &T,
) -> Result<bool, Error> {
let left = Model::try_from(left)?;
let right = Model::try_from(right)?;
Ok(super::is_equal_ignoring_audit_fields(&left, &right))
}
#[cfg(test)]
mod tests {
use crate::models::is_equal_ignoring_audit_fields;
use pbbson::Model;
use pbbson::bson::{DateTime, doc};
#[test]
fn can_compare_with_identity() {
let left = Model::from(doc! {"name": "Joe", "age": 23_u32});
let right = left.clone();
assert!(is_equal_ignoring_audit_fields(&left, &right));
}
#[test]
fn can_detect_equality_when_audit_fields_dont_match() {
let left = Model::from(doc! {"name": "Joe"});
let now = DateTime::now();
let right = Model::from(doc! {
"createdAt": now,
"name": "Joe",
});
assert!(is_equal_ignoring_audit_fields(&left, &right));
}
#[test]
fn can_detect_inequality_when_audit_fields_match() {
let now = DateTime::now();
let left = Model::from(doc! {
"createdAt": now,
"name": "Joe",
});
let right = Model::from(doc! {
"createdAt": now,
"name": "Jane",
});
assert!(!is_equal_ignoring_audit_fields(&left, &right));
}
}