1use linked_hash_map::LinkedHashMap;
2
3use crate::index::{IndexEntry, IndexEntryProperty};
4use crate::model::validators::ValidatorContext;
5use crate::model::Model;
6use crate::object_data::Id;
7use crate::object_data::{ObjectValue, ObjectValues};
8use crate::plugins::Plugins;
9use crate::utils::ModelPropertyVectors;
10use crate::HitError;
11use crate::Kernel;
12use crate::{errors::ValidationError, events::FieldListenerRef};
13use crate::{events::Listeners, hit_mod::hit_entry::HitEntry};
14use crate::{helpers::copy_object, index::Index};
15use crate::{hit_mod::helpers::can_move_object, ModelField};
16
17use std::cell::RefCell;
18use std::collections::HashMap;
19use std::rc::Rc;
20
21pub type HitPlugins = Plugins;
22pub type HitKernel = dyn Kernel;
23
24pub(crate) struct ModelIndex {
25 pub map: HashMap<String, Rc<Model>>,
26}
27
28impl ModelIndex {
29 pub fn new() -> Self {
30 ModelIndex {
31 map: HashMap::new(),
32 }
33 }
34}
35
36#[derive(Clone)]
37pub struct Hit {
38 pub index: Index,
39 pub(crate) model_index: Rc<RefCell<ModelIndex>>,
40 pub(crate) plugins: HitPlugins,
41 pub kernel: Rc<HitKernel>,
42 pub(crate) errors: ModelPropertyVectors<ValidationError>,
43 pub(crate) errors_subscriptions: Listeners<Vec<ValidationError>>,
44}
45
46impl Hit {
47 pub fn new(id: &str, model_type: &str, kernel: Rc<HitKernel>) -> Result<Hit, HitError> {
48 Hit::new_with_values(id, kernel, LinkedHashMap::new(), model_type)
49 }
50
51 pub fn import(&mut self, hit: Hit, parent: IndexEntryProperty) -> Result<(), HitError> {
54 let main_id = hit.get_main_object_id();
55 let get_parent = |x: &IndexEntry| {
56 if x.get_id() == main_id {
57 return Some(parent.clone());
58 }
59 return x.get_parent().clone();
60 };
61
62 for (id, value) in hit.index.index.iter() {
63 if id == main_id {
64 continue;
65 }
66 let value = value.borrow();
67
68 let new_entry = IndexEntry::new_raw(
69 id.clone(),
70 value.data.clone(),
71 get_parent(&value),
72 value.references.clone(),
73 );
74 let model = hit.get_model_or_error(&id)?;
75 self.model_index.borrow_mut().map.insert(id.clone(), model);
76 self.index.index.insert(id.clone(), new_entry);
77 }
78
79 let main = hit.get(&main_id).unwrap();
81 let model = hit.get_model_or_error(main_id)?;
82
83 self.insert(&model.get_name(), main_id, main.get_data(), parent, None)?;
84 Ok(())
85 }
86
87 pub fn new_with_values(
88 id: &str,
89 kernel: Rc<HitKernel>,
90 values: ObjectValues,
91 model_type: &str,
92 ) -> Result<Hit, HitError> {
93 let mut model_index = ModelIndex::new();
94 let model = kernel.get_model(model_type)?;
95 model_index.map.insert(id.to_string(), model);
98 let model_index = Rc::new(RefCell::new(model_index));
99
100 let mut hit = Hit {
101 index: Index::new(id, LinkedHashMap::new())?,
102 model_index: model_index,
103 plugins: kernel.get_plugins(),
104 kernel: kernel,
105 errors: ModelPropertyVectors::new(),
106 errors_subscriptions: Listeners::new(),
107 };
108 for (key, value) in values.iter() {
109 hit.set(id, key, value.clone())?;
110 }
111 hit.validate_all()?;
112 Ok(hit)
113 }
114
115 pub fn contains_key(&self, key: &str) -> bool {
116 return self.model_index.borrow().map.contains_key(key);
117 }
118
119 fn field_is_reference_array(&self, target: &IndexEntryProperty) -> Result<bool, HitError> {
120 let target_model = self.get_model_or_error(&target.id)?;
121
122 let target_model_field = target_model
123 .get_field(&target.property)
124 .ok_or(HitError::PropertyNotFound((&target.property).to_string()))?;
125
126 let target_model_field_borrowed = target_model_field.borrow();
127 if target_model_field_borrowed.is_vec_reference() {
128 Ok(true)
129 } else {
130 Err(HitError::InvalidDataType())
131 }
132 }
133
134 pub fn insert_reference(
135 &mut self,
136 id: &str,
137 target: IndexEntryProperty,
138 before_id: Option<String>,
139 ) -> Result<(), HitError> {
140 for plugin in self.plugins.reference_plugins.clone().iter() {
142 plugin.borrow_mut().on_before_add_reference(
143 self,
144 &id.to_string(),
145 &target,
146 &before_id,
147 )?;
148 }
149
150 let is_valid = self.field_is_reference_array(&target)?;
151
152 if is_valid {
153 self.index
154 .insert_reference(id, target.clone(), before_id.clone())?;
155 for plugin in self.plugins.reference_plugins.clone().iter() {
156 plugin.borrow_mut().on_after_add_reference(
157 self,
158 &id.to_string(),
159 &target,
160 &before_id,
161 )?;
162 }
163 Ok(())
164 } else {
165 Err(HitError::InvalidReference(id.to_string()))
166 }
167 }
168
169 pub fn remove_reference(
170 &mut self,
171 id: &str,
172 parent: IndexEntryProperty,
173 ) -> Result<(), HitError> {
174 for plugin in self.plugins.reference_plugins.clone().iter() {
176 plugin
177 .borrow_mut()
178 .on_before_remove_reference(self, &id.to_string(), &parent)?;
179 }
180
181 let target_model = self.get_model_or_error(&parent.id)?;
183 let target_property = target_model
184 .get_field(&parent.property)
185 .ok_or(HitError::PropertyNotFound((&parent.property).into()))?;
186 let target_property = target_property.borrow();
187 if target_property.is_vec_reference() {
188 self.index.remove_reference(id, parent.clone())?;
189
190 for plugin in self.plugins.reference_plugins.clone().iter() {
191 plugin
192 .borrow_mut()
193 .on_after_remove_reference(self, &id.to_string(), &parent)?;
194 }
195 Ok(())
196 } else {
197 Err(HitError::InvalidDataType())
198 }
199 }
200
201 pub fn move_reference(
202 &mut self,
203 id: &str,
204 target: IndexEntryProperty,
205 before_id: Option<Id>,
206 ) -> Result<(), HitError> {
207 for plugin in self.plugins.reference_plugins.clone().iter() {
209 plugin
210 .borrow_mut()
211 .on_before_remove_reference(self, &id.to_string(), &target)?;
212 }
213
214 let target_model = self.get_model_or_error(&target.id)?;
216 let target_property = target_model
217 .get_field(&target.property)
218 .ok_or(HitError::PropertyNotFound((&target.property).into()))?;
219 let target_property = target_property.borrow();
220 if target_property.is_vec_reference() {
221 self.index
222 .move_reference(id, target.clone(), before_id.clone())?;
223
224 for plugin in self.plugins.reference_plugins.clone().iter() {
225 plugin
226 .borrow_mut()
227 .on_after_remove_reference(self, &id.to_string(), &target)?;
228 }
229 Ok(())
230 } else {
231 Err(HitError::InvalidDataType())
232 }
233 }
234
235 pub fn get_references(&self, id: &str) -> Result<Vec<IndexEntryProperty>, HitError> {
236 self.index.get_references(id)
237 }
238
239 pub fn find_references_recursive(
240 &self,
241 id: &str,
242 ) -> Result<(HashMap<String, Vec<IndexEntryProperty>>, Vec<String>), HitError> {
243 self.index.find_references_recursive(id)
244 }
245
246 pub fn remove_object(&mut self, id: &str) -> Result<Vec<String>, HitError> {
247 let entry = self.index.get(id).ok_or(HitError::IDNotFound(
248 id.to_string(),
249 "remove_object entry".to_string(),
250 ))?;
251 let model = self.get_model(id).ok_or(HitError::IDNotFound(
252 id.to_string(),
253 "remove_object model".to_string(),
254 ))?;
255
256 for plugin in self.plugins.delete_plugins.clone().iter() {
258 plugin.borrow_mut().on_before_delete_entry(
259 &HitEntry {
260 entry: entry.clone(),
261 model: model.clone(),
262 },
263 self,
264 )?;
265 }
266
267 let id_list = self.index.remove_object(id)?;
268
269 for plugin in self.plugins.delete_plugins.clone().iter() {
271 plugin.borrow_mut().on_after_delete_entry(
272 &HitEntry {
273 entry: entry.clone(),
274 model: model.clone(),
275 },
276 self,
277 )?;
278 }
279
280 for id in id_list.iter() {
282 let mut model_index = self.model_index.borrow_mut();
283 model_index.map.remove(id);
284 }
285 Ok(id_list)
286 }
287
288 pub fn can_move_object(
289 &self,
290 id: &str,
291 target_id: &str,
292 target_model: &str,
293 property: &str,
294 ) -> Result<(), HitError> {
295 can_move_object(&self, id, target_id, target_model, property)
296 }
297
298 pub fn move_object(
299 &mut self,
300 id: &str,
301 target: IndexEntryProperty,
302 before_id: Option<String>,
303 ) -> Result<(), HitError> {
304 let target_model = self.get_model_or_error(&target.id)?;
306 if !self.model_index.borrow().map.contains_key(id) {
307 return Err(HitError::IDNotFound(id.into(), "move_object".into()));
308 }
309 let original_parent = self
310 .get_parent(id)
311 .ok_or(HitError::CannotMoveRootObject())?;
312
313 for plugin in self.plugins.plugins.iter() {
314 plugin.borrow_mut().on_before_move_subobject(
315 id.clone(),
316 target.clone(),
317 before_id.clone(),
318 &self,
319 )?;
320 }
321
322 self.can_move_object(id, &target.id, target_model.get_name(), &target.property)?;
323 self.index
324 .move_object(id, target.clone(), before_id.clone())?;
325 let plugins = { self.plugins.plugins.clone() };
326 for plugin in plugins.iter() {
327 plugin.borrow_mut().on_after_move_subobject(
328 id.clone(),
329 target.clone(),
330 original_parent.clone(),
331 before_id.clone(),
332 self,
333 )?;
334 }
335 Ok(())
336 }
337
338 pub fn copy_object(
339 &mut self,
340 id: Id,
341 target: IndexEntryProperty,
342 before_id: Option<String>,
343 ) -> Result<Id, HitError> {
344 let target_model = self.get_model_or_error(&target.id)?;
345 if !self.model_index.borrow().map.contains_key(&id) {
346 return Err(HitError::IDNotFound(id.into(), "copy_object".into()));
347 }
348 self.can_move_object(&id, &target.id, target_model.get_name(), &target.property)?;
349
350 let id = copy_object(self, &id, target, before_id)?;
351 return Ok(id);
352 }
353
354 pub fn get_model(&self, id: &str) -> Option<Rc<Model>> {
355 match self.model_index.borrow().map.get(id) {
356 Some(model) => Some(model.clone()),
357 None => None,
358 }
359 }
360
361 fn get_model_or_error(&self, id: &str) -> Result<Rc<Model>, HitError> {
362 self.get_model(id)
363 .ok_or(HitError::IDNotFound(id.into(), "get_model".into()))
364 }
365 pub fn get(&self, id: &str) -> Option<HitEntry> {
379 let index_entry = self.index.get(id)?;
380 let model = self.model_index.borrow();
381 let model = model.map.get(id)?;
382 Some(HitEntry {
383 entry: index_entry,
384 model: model.clone(),
385 })
386 }
387
388 pub fn get_value(&self, id: &str, property: &str) -> Option<ObjectValue> {
389 self.index.get_value(id, property)
390 }
391
392 pub fn set(&mut self, id: &str, property: &str, value: ObjectValue) -> Result<(), HitError> {
393 let entry = self
394 .get(id)
395 .ok_or(HitError::IDNotFound(id.to_string(), "set".into()))?;
396 let model_field = entry
397 .model
398 .get_field(property)
399 .ok_or(HitError::PropertyNotFound(property.to_string()))?;
400
401 let old_value = self.get_value(id, property);
402
403 for plugin in self.plugins.plugins.iter() {
404 plugin.borrow_mut().on_before_set_value(
405 IndexEntryProperty {
406 id: id.into(),
407 property: property.into(),
408 },
409 &value,
410 &old_value,
411 &self,
412 )?;
413 }
414
415 if !model_field.borrow().accepts_for_set(
417 &value,
418 &ValidatorContext {
419 id: id,
420 property: property,
421 index: Rc::new(self),
422 },
423 ) {
424 return Err(HitError::InvalidDataType());
425 }
426
427 self.index.set_value(id, property, value.clone())?;
428
429 for plugin in { self.plugins.plugins.clone() }.iter() {
430 plugin.borrow_mut().on_after_set_value(
431 IndexEntryProperty {
432 id: id.into(),
433 property: property.into(),
434 },
435 &value,
436 &old_value,
437 self,
438 )?;
439 }
440
441 self._validate_field(model_field, id, property, value)?;
442
443 Ok(())
444 }
445
446 fn validate_inserted_values(
447 &mut self,
448 new_object_model: &Rc<Model>,
449 id: &str,
450 values: &ObjectValues,
451 ) -> Result<ObjectValues, HitError> {
452 let mut ordered_values: ObjectValues = LinkedHashMap::new();
455 for (property, model_field) in new_object_model.fields.iter() {
456 match values.get(property) {
458 Some(value) => {
459 match value {
460 ObjectValue::Null => {}
461 _ => {
462 if !model_field.borrow().accepts_for_set(
463 &value,
464 &ValidatorContext {
465 id: id,
466 property: property,
467 index: Rc::new(self),
468 },
469 ) {
470 return Err(HitError::InvalidDataType());
471 }
472 }
473 };
474 ordered_values.insert(property.to_string(), value.clone());
475 }
476 None => {
477 ordered_values.insert(property.to_string(), ObjectValue::Null);
478 }
479 }
480 }
481 Ok(ordered_values)
482 }
483
484 pub fn insert(
485 &mut self,
486 model_type: &str,
487 id: &str,
488 values: ObjectValues,
489 parent: IndexEntryProperty,
490 before_id: Option<String>,
491 ) -> Result<(), HitError> {
492 let new_object_model = self
493 .kernel
494 .get_model(&model_type.to_string())
495 .map_err(|_| HitError::ModelDoesNotExist(model_type.to_string()))?;
496
497 for plugin in self.get_plugins().plugins.iter() {
499 plugin.borrow_mut().on_before_add_entry(
500 new_object_model.clone(),
501 &id,
502 values.clone(),
503 parent.clone(),
504 &before_id,
505 &self,
506 )?;
507 }
508
509 let target_model = self.get_model_or_error(&parent.id)?;
510
511 let field = target_model
513 .get_field(&parent.property)
514 .ok_or(HitError::PropertyNotFound(parent.property.clone()))?;
515 let field = field.borrow();
516 if !field.is_vec_subobject() {
517 return Err(HitError::CannotInsertObjectInThisDataType());
518 }
519 if !field.accepts_model(&new_object_model) {
521 return Err(HitError::ModelNotAllowed(model_type.into()));
522 }
523
524 let values = self.validate_inserted_values(&new_object_model, id, &values)?;
525 self.index
527 .insert(id, values.clone(), parent.clone(), before_id.clone())?;
528 self.model_index
529 .borrow_mut()
530 .map
531 .insert(id.to_string(), new_object_model.clone());
532
533 for plugin in { self.get_plugins().plugins.clone() }.iter() {
535 plugin.borrow_mut().on_after_add_entry(
536 new_object_model.clone(),
537 &id,
538 values.clone(),
539 parent.clone(),
540 &before_id,
541 self,
542 )?;
543 }
544
545 Ok(())
546 }
547
548 pub fn get_plugins(&self) -> &HitPlugins {
549 return &self.plugins;
550 }
551 pub fn get_main_object_id(&self) -> &Id {
552 return &self.index.get_main_object_id();
553 }
554
555 pub fn subscribe_field(
556 &self,
557 id: &str,
558 field: &str,
559 listener: FieldListenerRef<ObjectValue>,
560 ) -> Result<String, HitError> {
561 let model = self.get_model_or_error(id)?;
562 model
563 .get_field(field)
564 .ok_or(HitError::PropertyNotFound(field.to_string()))?;
565
566 match self.index.get(id) {
567 Some(entry) => {
568 {
569 entry.borrow_mut().add_listener(field, listener.clone());
570 }
571
572 let listener_id = {
573 let borrow = listener.borrow();
574 borrow.get_unique_id().to_string()
575 };
576 Ok(listener_id)
577 }
578 None => Err(HitError::IDNotFound(
579 id.to_string(),
580 "subscribe_field".into(),
581 )),
582 }
583 }
584
585 pub fn unsubscribe_field(
586 &self,
587 id: &str,
588 field: &str,
589 listener_id: &str,
590 ) -> Result<(), HitError> {
591 match self.index.get(id) {
592 Some(entry) => {
593 entry.borrow_mut().remove_listener(field, listener_id)?;
594 Ok(())
595 }
596 None => Err(HitError::IDNotFound(
597 id.to_string(),
598 "unsubscribe_field".into(),
599 )),
600 }
601 }
602
603 pub fn get_parent(&self, id: &str) -> Option<IndexEntryProperty> {
604 self.get(id)?.get_parent()
605 }
606
607 pub fn get_parent_index(&self, id: &str) -> Option<usize> {
608 let parent = self.get_parent(id)?;
609 match self.get_value(&parent.id, &parent.property)? {
610 ObjectValue::VecSubObjects(parent_value) => {
611 parent_value.iter().position(|r| r.id == id)
612 }
613 _ => None,
614 }
615 }
616
617 fn _validate_field(
618 &mut self,
619 model_field: &Rc<RefCell<dyn ModelField>>,
620 id: &str,
621 property: &str,
622 value: ObjectValue,
623 ) -> Result<(), HitError> {
624 let validation_errors = model_field.borrow().validate(
625 &value,
626 &ValidatorContext {
627 id: &id.to_string(),
628 property: &property.to_string(),
629 index: Rc::new(self),
630 },
631 )?;
632 self.errors.delete(id, property);
633 match validation_errors.clone() {
634 None => {}
635 Some(validation_errors) => {
636 for error in validation_errors.into_iter() {
637 self.errors.add(id, property, error);
638 }
639 }
640 }
641
642 self.errors_subscriptions.dispatch_value(
645 &Self::get_validation_subscription_key(id, property),
646 &{
647 match validation_errors {
648 Some(validation_errors) => validation_errors,
649 None => vec![],
650 }
651 },
652 );
653
654 Ok(())
655 }
656
657 pub fn validate_field(&mut self, id: &str, property: &str) -> Result<(), HitError> {
658 let model = self.get_model_or_error(id)?;
659 let model_field = model
660 .get_field(property)
661 .ok_or(HitError::PropertyNotFound(property.to_string()))?;
662
663 let value = self.get_value(id, property);
664 self._validate_field(
665 model_field,
666 id,
667 property,
668 value.or(Some(ObjectValue::Null)).unwrap(),
669 )?;
670 Ok(())
671 }
672
673 fn get_validation_subscription_key(id: &str, field: &str) -> String {
674 format!("{}{}", id, field)
675 }
676 pub fn get_validation_errors(&self, id: &str, field: &str) -> Option<&Vec<ValidationError>> {
677 self.errors.get(id, field)
678 }
679 pub fn subscribe_field_validation(
680 &mut self,
681 id: &str,
682 field: &str,
683 listener: FieldListenerRef<Vec<ValidationError>>,
684 ) {
685 self.errors_subscriptions
686 .insert(&Self::get_validation_subscription_key(id, field), listener);
687 }
688
689 pub fn unsubscribe_field_validation(
690 &mut self,
691 id: &str,
692 field: &str,
693 listener_id: &str,
694 ) -> Result<(), HitError> {
695 self.errors_subscriptions.remove(
696 &Self::get_validation_subscription_key(id, field),
697 listener_id,
698 )
699 }
700
701 pub(crate) fn validate_all(&mut self) -> Result<(), HitError> {
702 let model_index = self.model_index.borrow().map.clone();
703
704 for (id, model) in model_index.iter() {
705 for (field_name, _field) in model.get_fields().iter() {
706 let model_field = model
707 .get_field(field_name)
708 .ok_or(HitError::PropertyNotFound(field_name.to_string()))?;
709 let value = self
710 .get_value(&id, field_name)
711 .or(Some(ObjectValue::Null))
712 .unwrap();
713 self._validate_field(model_field, &id, field_name, value)?;
714 }
715 }
716 Ok(())
717 }
718}