hit_data/import/
patches.rs1use std::rc::Rc;
2
3use linked_hash_map::LinkedHashMap;
4
5use crate::{hit_mod::IndexModelImporter, HitError, Hit, HitKernel, Patch, generic_import::finish_import, AddedEntry};
6
7use super::generic_import::import_data_object_values;
8
9
10pub fn import_from_patches<'a>(
11 patches: Vec<Patch>,
12 id: &str,
13 kernel: Rc<HitKernel>
14) -> Result<Hit, HitError> {
15 let mut entries = LinkedHashMap::new();
16 import_from_patches_and_entries(patches, id, kernel, &mut entries)
17}
18
19pub fn import_from_patches_and_entries<'a>(
20 patches: Vec<Patch>,
21 id: &str,
22 kernel: Rc<HitKernel>,
23 entries: &mut LinkedHashMap<String, AddedEntry>
24) -> Result<Hit, HitError> {
25 for patch in patches {
26 import_patch(patch, entries)?;
27 }
28
29 let mut importer = IndexModelImporter::new(id, kernel.clone());
30 for entry in entries.iter() {
31 let id = entry.0;
32 let added_entry = entry.1;
33 let model = {
34 kernel
35 .get_model(&added_entry.model)?
36 };
37 import_data_object_values(
38 model,
39 id.clone(),
40 added_entry.parent.clone(),
41 &mut importer,
42 added_entry.data.clone(),
43 )?;
44 }
45
46 let hit = finish_import(importer, kernel)?;
47 return Ok(hit);
48}
49
50pub fn apply_patches(hit: &Hit, patches: Vec<Patch>) -> Result<Hit, HitError> {
51 let mut entries = LinkedHashMap::new();
52 for entry in hit.index.iter() {
53 let model = hit.get_model(&entry.0).unwrap();
54 entries.insert(entry.0.to_string(), AddedEntry {
55 id: entry.0.clone(),
56 data: entry.1.borrow().data.clone(),
57 parent: entry.1.borrow().get_parent(),
58 model: model.get_name().to_string(),
59 });
60 }
61 import_from_patches_and_entries(patches, hit.get_main_object_id(), hit.kernel.clone(), &mut entries)
62}
63
64pub fn duplicate_hit(hit: &Hit) -> Result<Hit, HitError> {
65 apply_patches(hit, vec![])
66}
67
68fn import_patch<'a>(
69 patch: Patch,
70 entries: &mut LinkedHashMap<String, AddedEntry>,
71) -> Result<(), HitError> {
72 for deleted in patch.deleted.iter() {
73 entries.remove(deleted);
74 }
75 for added in patch.added.iter() {
76 entries.insert(added.id.clone(), added.clone());
77 }
78 for changed in patch.differences.iter() {
79 let entry = entries.get_mut(&changed.id).unwrap();
80 entry.data.remove(&changed.property);
81 entry
82 .data
83 .insert(changed.property.clone(), changed.new_value.clone());
84 }
85 return Ok(());
86}