use std::collections::btree_map::Iter as BTreeMapIter;
use std::fmt::Display;
use crate::document::{DocumentViewFields, DocumentViewId, DocumentViewValue};
use crate::Human;
type FieldKey = String;
#[derive(Debug, PartialEq, Clone)]
pub struct DocumentView {
pub(crate) id: DocumentViewId,
pub(crate) fields: DocumentViewFields,
}
impl DocumentView {
pub fn new(id: &DocumentViewId, fields: &DocumentViewFields) -> Self {
Self {
id: id.clone(),
fields: fields.clone(),
}
}
pub fn id(&self) -> &DocumentViewId {
&self.id
}
pub fn get(&self, key: &str) -> Option<&DocumentViewValue> {
self.fields.get(key)
}
pub fn keys(&self) -> Vec<String> {
self.fields.keys()
}
pub fn iter(&self) -> BTreeMapIter<FieldKey, DocumentViewValue> {
self.fields.iter()
}
pub fn len(&self) -> usize {
self.fields.len()
}
pub fn is_empty(&self) -> bool {
self.fields.is_empty()
}
pub fn fields(&self) -> &DocumentViewFields {
&self.fields
}
}
impl Display for DocumentView {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.id)
}
}
impl Human for DocumentView {
fn display(&self) -> String {
format!("<DocumentView {}>", self.id.display())
}
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use crate::document::materialization::reduce;
use crate::document::DocumentViewValue;
use crate::operation::traits::AsVerifiedOperation;
use crate::operation::{OperationFields, OperationId, OperationValue, VerifiedOperation};
use crate::test_utils::constants::HASH;
use crate::test_utils::fixtures::{
document_view_id, operation_fields, verified_operation, verified_operation_with_schema,
};
use crate::Human;
use super::{DocumentView, DocumentViewId};
#[rstest]
fn from_single_create_op(
verified_operation: VerifiedOperation,
document_view_id: DocumentViewId,
operation_fields: OperationFields,
) {
let (view, is_edited, is_deleted) = reduce(&[verified_operation.clone()]);
let document_view = DocumentView::new(&document_view_id, &view.unwrap());
assert!(!document_view.is_empty());
assert!(!is_edited);
assert!(!is_deleted);
assert_eq!(document_view.len(), 8);
assert_eq!(document_view.keys(), operation_fields.keys());
for key in operation_fields.keys() {
assert_eq!(
document_view.get(&key).unwrap(),
&DocumentViewValue::new(
verified_operation.id(),
operation_fields.get(&key).unwrap(),
),
);
}
}
#[rstest]
fn with_update_op(
#[from(verified_operation_with_schema)] create_operation: VerifiedOperation,
#[from(verified_operation_with_schema)]
#[with(Some(operation_fields(vec![
("username", OperationValue::String("yahoo".to_owned())),
("height", OperationValue::Float(100.23)),
("age", OperationValue::Integer(12)),
("is_admin", OperationValue::Boolean(true)),
])), Some(HASH.parse().unwrap()))]
update_operation: VerifiedOperation,
document_view_id: DocumentViewId,
) {
let (view, is_edited, is_deleted) = reduce(&[create_operation, update_operation.clone()]);
let document_view = DocumentView::new(&document_view_id, &view.unwrap());
assert_eq!(
document_view.get("username").unwrap(),
&DocumentViewValue::new(
update_operation.id(),
&OperationValue::String("yahoo".to_owned()),
)
);
assert_eq!(
document_view.get("height").unwrap(),
&DocumentViewValue::new(update_operation.id(), &OperationValue::Float(100.23)),
);
assert_eq!(
document_view.get("age").unwrap(),
&DocumentViewValue::new(update_operation.id(), &OperationValue::Integer(12)),
);
assert_eq!(
document_view.get("is_admin").unwrap(),
&DocumentViewValue::new(update_operation.id(), &OperationValue::Boolean(true))
);
assert!(is_edited);
assert!(!is_deleted);
}
#[rstest]
fn string_representation(verified_operation: VerifiedOperation) {
let operation_1 = "0020b177ec1bf26dfb3b7010d473e6d44713b29b765b99c6e60ecbfae742de496543"
.parse::<OperationId>()
.unwrap();
let operation_2 = "0020d3235c8fe6f58608200851b83cd8482808eb81e4c6b4b17805bba57da9f16e79"
.parse::<OperationId>()
.unwrap();
let document_view_id = DocumentViewId::new(&[operation_1, operation_2]);
let (view, _, _) = reduce(&[verified_operation]);
let document_view = DocumentView::new(&document_view_id, &view.unwrap());
assert_eq!(
format!("{}", document_view),
"0020b177ec1bf26dfb3b7010d473e6d44713b29b765b99c6e60ecbfae742de496543_0020d3235c8fe6f58608200851b83cd8482808eb81e4c6b4b17805bba57da9f16e79"
);
assert_eq!(document_view.display(), "<DocumentView 496543_f16e79>");
}
}