use serde::Serialize;
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize)]
pub struct ItemUpdate {
pub item_name: Option<String>,
pub item_pos: usize,
pub fields: HashMap<String, Option<String>>,
pub changed_fields: HashMap<String, String>,
pub is_snapshot: bool,
}
impl ItemUpdate {
pub fn get_changed_fields(&self) -> HashMap<String, String> {
self.changed_fields.clone()
}
pub fn get_changed_fields_by_position(&self) -> HashMap<usize, String> {
self.changed_fields
.iter()
.map(|(name, value)| (self.get_field_position(name), value.clone()))
.collect()
}
pub fn get_fields(&self) -> HashMap<String, Option<String>> {
self.fields.clone()
}
pub fn get_fields_by_position(&self) -> HashMap<usize, Option<String>> {
self.fields
.iter()
.map(|(name, value)| (self.get_field_position(name), value.clone()))
.collect()
}
pub fn get_item_name(&self) -> Option<&str> {
self.item_name.as_deref()
}
pub fn get_item_pos(&self) -> usize {
self.item_pos
}
pub fn get_value(&self, field_name_or_pos: &str) -> Option<&str> {
match field_name_or_pos.parse::<usize>() {
Ok(pos) => self
.fields
.iter()
.find(|(name, _)| self.get_field_position(name) == pos)
.and_then(|(_, value)| value.as_deref()),
Err(_) => self
.fields
.get(field_name_or_pos)
.and_then(|v| v.as_deref()),
}
}
pub fn get_value_as_json_patch_if_available(&self, _field_name_or_pos: &str) -> Option<String> {
None
}
pub fn is_snapshot(&self) -> bool {
self.is_snapshot
}
pub fn is_value_changed(&self, field_name_or_pos: &str) -> bool {
match field_name_or_pos.parse::<usize>() {
Ok(pos) => self
.changed_fields
.iter()
.any(|(name, _)| self.get_field_position(name) == pos),
Err(_) => self.changed_fields.contains_key(field_name_or_pos),
}
}
fn get_field_position(&self, field_name: &str) -> usize {
match field_name {
"field1" => 1,
"field2" => 2,
"field3" => 3,
_ => 0,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn test_get_fields_by_position() {
let update = create_test_item_update();
let fields_by_position = update.get_fields_by_position();
assert_eq!(fields_by_position.len(), 3); assert_eq!(
fields_by_position.get(&1),
Some(&Some("value1".to_string()))
);
assert_eq!(
fields_by_position.get(&2),
Some(&Some("value2".to_string()))
);
assert_eq!(fields_by_position.get(&3), Some(&None));
}
#[test]
fn test_get_changed_fields_by_position() {
let update = create_test_item_update();
let changed_fields_by_position = update.get_changed_fields_by_position();
assert_eq!(changed_fields_by_position.len(), 2); assert_eq!(
changed_fields_by_position.get(&1),
Some(&"value1".to_string())
);
assert_eq!(
changed_fields_by_position.get(&2),
Some(&"value2".to_string())
);
}
fn create_test_item_update() -> ItemUpdate {
let mut fields = HashMap::new();
fields.insert("field1".to_string(), Some("value1".to_string()));
fields.insert("field2".to_string(), Some("value2".to_string()));
fields.insert("field3".to_string(), None);
let mut changed_fields = HashMap::new();
changed_fields.insert("field1".to_string(), "value1".to_string());
changed_fields.insert("field2".to_string(), "value2".to_string());
ItemUpdate {
item_name: Some("test_item".to_string()),
item_pos: 1,
fields,
changed_fields,
is_snapshot: false,
}
}
#[test]
fn test_get_item_name() {
let update = create_test_item_update();
assert_eq!(update.get_item_name(), Some("test_item"));
let mut update_no_name = create_test_item_update();
update_no_name.item_name = None;
assert_eq!(update_no_name.get_item_name(), None);
}
#[test]
fn test_get_item_pos() {
let update = create_test_item_update();
assert_eq!(update.get_item_pos(), 1);
}
#[test]
fn test_get_fields() {
let update = create_test_item_update();
let fields = update.get_fields();
assert_eq!(fields.len(), 3);
assert_eq!(fields.get("field1"), Some(&Some("value1".to_string())));
assert_eq!(fields.get("field2"), Some(&Some("value2".to_string())));
assert_eq!(fields.get("field3"), Some(&None));
}
#[test]
fn test_get_changed_fields() {
let update = create_test_item_update();
let changed_fields = update.get_changed_fields();
assert_eq!(changed_fields.len(), 2);
assert_eq!(changed_fields.get("field1"), Some(&"value1".to_string()));
assert_eq!(changed_fields.get("field2"), Some(&"value2".to_string()));
assert!(!changed_fields.contains_key("field3"));
}
#[test]
fn test_get_value() {
let update = create_test_item_update();
assert_eq!(update.get_value("field1"), Some("value1"));
assert_eq!(update.get_value("field2"), Some("value2"));
assert_eq!(update.get_value("field3"), None);
assert_eq!(update.get_value("non_existent"), None);
}
#[test]
fn test_is_snapshot() {
let update = create_test_item_update();
assert!(!update.is_snapshot());
let mut snapshot_update = create_test_item_update();
snapshot_update.is_snapshot = true;
assert!(snapshot_update.is_snapshot());
}
#[test]
fn test_is_value_changed() {
let update = create_test_item_update();
assert!(update.is_value_changed("field1"));
assert!(update.is_value_changed("field2"));
assert!(!update.is_value_changed("field3"));
}
#[test]
fn test_get_value_as_json_patch_if_available() {
let update = create_test_item_update();
assert_eq!(update.get_value_as_json_patch_if_available("field1"), None);
}
#[test]
fn test_get_field_position() {
let update = create_test_item_update();
assert_eq!(update.get_field_position("field1"), 1);
assert_eq!(update.get_field_position("field2"), 2);
assert_eq!(update.get_field_position("field3"), 3);
assert_eq!(update.get_field_position("non_existent_field"), 0);
}
}