1use std::path::Path;
5
6use crate::{error::Result, XvcStore};
7use crate::{Storable, XvcEntity};
8use std::fmt::Debug;
9
10#[derive(Debug, Clone)]
13pub struct R11Store<T, U>
14where
15 T: Storable,
16 U: Storable,
17{
18 pub left: XvcStore<T>,
20 pub right: XvcStore<U>,
22}
23
24impl<T, U> R11Store<T, U>
25where
26 T: Storable,
27 U: Storable,
28{
29 pub fn new() -> Self {
39 Self {
40 left: XvcStore::<T>::new(),
41 right: XvcStore::<U>::new(),
42 }
43 }
44
45 pub fn insert(&mut self, entity: &XvcEntity, left_component: T, right_component: U) {
57 self.left.insert(*entity, left_component);
58 self.right.insert(*entity, right_component);
59 }
60
61 pub fn left_to_right(&self, entity: &XvcEntity) -> Option<(&XvcEntity, &U)> {
70 self.right.get_key_value(entity)
71 }
72
73 pub fn right_to_left(&self, entity: &XvcEntity) -> Option<(&XvcEntity, &T)> {
82 self.left.get_key_value(entity)
83 }
84
85 pub fn tuple(&self, entity: &XvcEntity) -> (Option<&T>, Option<&U>) {
94 (self.left.get(entity), self.right.get(entity))
95 }
96
97 pub fn entity_by_left(&self, left_element: &T) -> Option<XvcEntity> {
99 match self.left.entities_for(left_element) {
100 Some(entities) => {
101 if entities.len() == 1 {
102 Some(entities[0])
103 } else if entities.is_empty() {
104 None
105 } else {
106 panic!("Multiple entities found for {left_element:?}");
107 }
108 }
109 None => None,
110 }
111 }
112
113 pub fn entity_by_right(&self, right_element: &U) -> Option<XvcEntity> {
115 match self.right.entities_for(right_element) {
116 None => None,
117 Some(vec_e) => vec_e.first().copied(),
118 }
119 }
120
121 pub fn remove(&mut self, entity: XvcEntity) {
123 self.left.remove(entity);
124 self.right.remove(entity);
125 }
126
127 pub fn lookup_by_left(&self, left_element: &T) -> Option<&U> {
129 match self.left.entity_by_value(left_element) {
130 None => None,
131 Some(xe) => self.right.get(&xe),
132 }
133 }
134
135 pub fn lookup_by_right(&self, right_element: &U) -> Option<&T> {
137 match self.right.entity_by_value(right_element) {
138 None => None,
139 Some(xe) => self.left.get(&xe),
140 }
141 }
142
143 pub fn filter(&self, predicate: impl Fn(&T, &U) -> bool) -> R11Store<T, U> {
145 let mut rs = R11Store::<T, U>::new();
146 for (entity, left) in self.left.iter() {
147 if let Some(right) = self.right.get(entity) {
148 if predicate(left, right) {
149 rs.insert(entity, left.clone(), right.clone());
150 }
151 }
152 }
153 rs
154 }
155}
156
157impl<T, U> R11Store<T, U>
158where
159 T: Storable,
160 U: Storable,
161{
162 pub fn load_r11store(store_root: &Path) -> Result<R11Store<T, U>> {
164 let left = XvcStore::<T>::load_store(store_root)?;
165 let right = XvcStore::<U>::load_store(store_root)?;
166
167 Ok(R11Store { left, right })
168 }
169
170 pub fn save_r11store(&self, store_root: &Path) -> Result<()> {
172 self.left.save(store_root)?;
173 self.right.save(store_root)
174 }
175}
176
177impl<T, U> Default for R11Store<T, U>
178where
179 T: Storable,
180 U: Storable,
181{
182 fn default() -> Self {
183 Self::new()
184 }
185}
186
187#[cfg(test)]
188mod test {
189
190 use super::*;
191 use crate::error::Result;
192 #[test]
193 fn test_new() -> Result<()> {
194 let rs1 = R11Store::<String, i32> {
195 left: XvcStore::<String>::new(),
196 right: XvcStore::<i32>::new(),
197 };
198
199 let rs2 = R11Store::<String, i32>::new();
200
201 assert!(rs1.right.len() == rs2.right.len());
202 assert!(rs1.left.len() == rs2.left.len());
203
204 Ok(())
205 }
206
207 #[test]
208 fn test_insert() -> Result<()> {
209 let mut rs = R11Store::<String, String>::new();
210 let entity: XvcEntity = (100, 12830912380).into();
211 rs.insert(&entity, "left component".into(), "right component".into());
212 assert!(rs.left[&entity] == "left component");
213 assert!(rs.right[&entity] == "right component");
214 Ok(())
215 }
216
217 #[test]
218 fn test_left_to_right() -> Result<()> {
219 let mut rs = R11Store::<String, String>::new();
220 let entity: XvcEntity = (100, 218021380921).into();
221 rs.insert(
222 &entity,
223 "left component".into(),
224 "right component".to_string(),
225 );
226 assert!(rs.left_to_right(&entity) == Some((&entity, &"right component".to_string())));
227 assert!(rs.left_to_right(&(101, 921309218309).into()).is_none());
228 Ok(())
229 }
230 #[test]
231 fn test_right_to_left() -> Result<()> {
232 let mut rs = R11Store::<String, String>::new();
233 let entity: XvcEntity = (100, 128012389012).into();
234 rs.insert(&entity, "left component".into(), "right component".into());
235 assert!(rs.right_to_left(&entity) == Some((&entity, &"left component".to_string())));
236 assert!(rs.right_to_left(&(101, 8120938120931).into()).is_none());
237 Ok(())
238 }
239
240 #[test]
241 fn test_tuple() -> Result<()> {
242 let mut rs = R11Store::<String, String>::new();
243 let entity: XvcEntity = (100, 123980123819203).into();
244 rs.insert(&entity, "left component".into(), "right component".into());
245 let t = rs.tuple(&entity);
246 assert!(t.0 == Some(&"left component".to_string()));
247 assert!(t.1 == Some(&"right component".to_string()));
248 Ok(())
249 }
250}