xvc_ecs/ecs/rmnstore.rs
1//! Stores arbitrarliy interrelated elements.
2//!
3//! This is not used in Xvc at the moment.
4//! It uses `XvcStore<ChildEntity<T, U>>` and `XvcStore<ChildEntity<U, T>>` to specify two
5//! [crate::R1NStore] 's that keep each other's relationship. It can be deprecated if there seems
6//! not to be a use case.
7//!
8//! A possible use case might be in experiments. Experiments vs files may have M-N relationships,
9//! each file can be affected by multiple experiments and each experiment may be affecting multiple
10//! files. I'll wait to deprecate this until all major features are implemented.
11use std::fmt::Debug;
12use std::path::Path;
13
14use crate::error::Result;
15use crate::ChildEntity;
16use crate::{Storable, XvcStore};
17
18/// RMNStore is M-N RelationStore, where we store arbitrary relationships between two entities. It
19/// doesn't have any semantics except binding two entities together.
20#[derive(Debug, Clone)]
21pub struct RMNStore<T, U>
22where
23 T: Storable,
24 U: Storable,
25{
26 /// The store for M side of the relationships
27 pub left: XvcStore<T>,
28 /// The store for N side of the relationships
29 pub right: XvcStore<U>,
30 /// Parent-child relationships from left to right
31 pub left_to_right: XvcStore<ChildEntity<T, U>>,
32 /// Parent-child relationships from right to left
33 pub right_to_left: XvcStore<ChildEntity<U, T>>,
34}
35
36impl<T, U> RMNStore<T, U>
37where
38 T: Storable,
39 U: Storable,
40{
41 /// Loads store from the directory under store root named after types
42 pub fn load_rmnstore(store_root: &Path) -> Result<RMNStore<T, U>> {
43 let left = XvcStore::<T>::load_store(store_root)?;
44 let right = XvcStore::<U>::load_store(store_root)?;
45 let left_to_right = XvcStore::<ChildEntity<T, U>>::load_store(store_root)?;
46 let right_to_left = XvcStore::<ChildEntity<U, T>>::load_store(store_root)?;
47 Ok(RMNStore {
48 left,
49 right,
50 left_to_right,
51 right_to_left,
52 })
53 }
54
55 /// Saves the store to directory created by store root and type names
56 pub fn save_rmnstore(store: &Self, store_root: &Path) -> Result<()> {
57 store.left.save(store_root)?;
58 store.right.save(store_root)?;
59 store.left_to_right.save(store_root)?;
60 store.right_to_left.save(store_root)
61 }
62}