1use super::XvcEntity;
4use crate::error::{Error, Result};
5use crate::{HStore, Storable, XvcStore};
6use serde::{Deserialize, Serialize};
7use std::fmt::Debug;
8use std::marker::PhantomData;
9use std::ops::Deref;
10use std::path::Path;
11
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
18pub struct ChildEntity<T: Storable, U: Storable>(XvcEntity, PhantomData<T>, PhantomData<U>);
19
20impl<T: Storable, U: Storable> Storable for ChildEntity<T, U> {
21 fn type_description() -> String {
22 format!(
23 "{}-{}-r1n",
24 <T as Storable>::type_description(),
25 <U as Storable>::type_description()
26 )
27 }
28}
29
30impl<T: Storable, U: Storable> From<XvcEntity> for ChildEntity<T, U> {
31 fn from(xe: XvcEntity) -> Self {
32 Self(xe, PhantomData, PhantomData)
33 }
34}
35
36impl<T: Storable, U: Storable> From<ChildEntity<T, U>> for XvcEntity {
37 fn from(r1ne: ChildEntity<T, U>) -> Self {
38 r1ne.0
39 }
40}
41
42impl<T: Storable, U: Storable> Deref for ChildEntity<T, U> {
43 type Target = XvcEntity;
44
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49
50#[derive(Debug, Clone)]
53pub struct R1NStore<T, U>
54where
55 T: Storable,
56 U: Storable,
57{
58 pub parents: XvcStore<T>,
60 pub children: XvcStore<U>,
62 pub child_parents: XvcStore<ChildEntity<U, T>>,
65}
66
67impl<T, U> R1NStore<T, U>
68where
69 T: Storable,
70 U: Storable,
71{
72 pub fn insert(
75 &mut self,
76 parent_entity: XvcEntity,
77 parent_component: T,
78 child_entity: XvcEntity,
79 child_component: U,
80 ) -> Option<XvcEntity> {
81 match self.parents.get(&parent_entity) {
82 None => {
83 self.parents.insert(parent_entity, parent_component);
84 }
85 Some(value) => {
86 if *value != parent_component {
87 self.parents.update(parent_entity, parent_component);
88 }
89 }
90 }
91
92 self.children.insert(child_entity, child_component);
93 self.child_parents
95 .insert(child_entity, parent_entity.into())
96 .map(XvcEntity::from)
97 }
98
99 pub fn children_of(&self, parent_entity: &XvcEntity) -> Result<HStore<U>> {
101 let related_entities = self.child_parents.iter().filter_map(|(child, parent)| {
102 if *parent == (*parent_entity).into() {
103 Some(*child)
104 } else {
105 None
106 }
107 });
108 self.children.subset(related_entities)
109 }
110
111 pub fn parent_of(&self, child_entity: &XvcEntity) -> Result<(&ChildEntity<U, T>, &T)> {
113 match self.child_parents.get(child_entity) {
114 None => Err(Error::NoParentEntityFound {
115 entity: (*child_entity),
116 }),
117 Some(p_e) => {
118 let (_, v) = self
119 .parents
120 .get_key_value(p_e)
121 .ok_or(Error::NoParentEntityFound {
122 entity: *child_entity,
123 })?;
124 Ok((p_e, v))
125 }
126 }
127 }
128
129 pub fn remove_child(&mut self, child_entity: XvcEntity) -> Result<()> {
131 self.child_parents.remove(child_entity);
132 self.children.remove(child_entity);
133 Ok(())
134 }
135}
136
137impl<T, U> R1NStore<T, U>
138where
139 T: Storable,
140 U: Storable,
141{
142 pub fn load_r1nstore(store_root: &Path) -> Result<R1NStore<T, U>> {
144 let parents = XvcStore::<T>::load_store(store_root)?;
145 let children = XvcStore::<U>::load_store(store_root)?;
146 let child_parents = XvcStore::<ChildEntity<U, T>>::load_store(store_root)?;
147
148 Ok(R1NStore {
149 parents,
150 children,
151 child_parents,
152 })
153 }
154
155 pub fn save_r1nstore(store: &Self, store_root: &Path) -> Result<()> {
157 store.parents.save(store_root)?;
158 store.children.save(store_root)?;
159 store.child_parents.save(store_root)
160 }
161}