1use std::borrow::{Borrow, Cow};
18use std::collections::{BTreeMap, BTreeSet};
19use std::fmt::Debug;
20use std::iter::once;
21
22use slotmap::{Key, SecondaryMap};
23
24use crate::interner::{DenseSlottedBTreeInterner, Interner};
25
26#[derive(Clone, Debug)]
28#[cfg_attr(
29 feature = "serde",
30 derive(serde::Serialize, serde::Deserialize),
31 serde(default, rename_all = "camelCase")
32)]
33#[cfg_attr(feature = "reactive", derive(reactive_stores::Store))]
34pub struct Category<ObjKey, Value, FieldKey, Field>
35where
36 ObjKey: Key,
37 FieldKey: Key,
38 Field: Clone + Debug + Ord,
39{
40 values: SecondaryMap<ObjKey, Value>,
42
43 objects_by_field: SecondaryMap<FieldKey, BTreeSet<ObjKey>>,
45
46 field_interner: DenseSlottedBTreeInterner<FieldKey, Field>,
48}
49
50impl<ObjKey, Value, FieldKey, Field> Default for Category<ObjKey, Value, FieldKey, Field>
51where
52 ObjKey: Key,
53 FieldKey: Key,
54 Field: Clone + Debug + Ord,
55{
56 fn default() -> Self {
57 Self {
58 values: SecondaryMap::default(),
59 objects_by_field: SecondaryMap::default(),
60 field_interner: DenseSlottedBTreeInterner::default(),
61 }
62 }
63}
64
65impl<ObjKey, Value, FieldKey, Field> Category<ObjKey, Value, FieldKey, Field>
67where
68 ObjKey: Key,
69 FieldKey: Key,
70 Field: Clone + Debug + Ord,
71{
72 pub fn new() -> Self {
74 Self::default()
75 }
76
77 pub fn field_key_interned(&self, name: &Field) -> Option<FieldKey> {
80 self.field_interner.get_key(name)
81 }
82
83 pub fn field_key(&mut self, name: Cow<'_, Field>) -> FieldKey {
85 self.field_interner.intern(name)
86 }
87
88 pub fn field_name(&self, key: FieldKey) -> Option<&Field> {
90 self.field_interner.get_value(key)
91 }
92
93 pub fn num_objects(&self) -> usize {
95 self.values.len()
96 }
97
98 pub fn object_keys(&self) -> impl Iterator<Item = ObjKey> {
100 self.values.keys()
101 }
102
103 pub fn num_fields(&self) -> usize {
105 self.field_interner.len()
106 }
107
108 pub fn field_names(&self) -> impl Iterator<Item = &Field> {
110 self.field_interner.values()
111 }
112
113 pub fn field_keys(&self) -> impl Iterator<Item = FieldKey> {
115 self.field_interner.keys()
116 }
117
118 pub fn field_items(&self) -> impl Iterator<Item = (FieldKey, &Field)> {
120 self.field_interner.items()
121 }
122
123 pub fn object_value(&self, obj: ObjKey) -> Option<&Value> {
125 self.values.get(obj)
126 }
127
128 pub fn objects_with_field(&self, field: FieldKey) -> Option<&BTreeSet<ObjKey>> {
130 self.objects_by_field.get(field)
131 }
132
133 pub fn objects_with_field_name(&self, name: &Field) -> Option<&BTreeSet<ObjKey>> {
135 let key = self.field_key_interned(name)?;
136 self.objects_with_field(key)
137 }
138
139 pub fn contains_object(&self, obj: ObjKey) -> bool {
141 self.values.contains_key(obj)
142 }
143
144 pub fn contains_field(&self, field: FieldKey) -> bool {
147 self.objects_by_field.contains_key(field)
148 }
149
150 pub fn contains_field_name<Name: Borrow<Field>>(&self, name: Name) -> bool {
152 self.field_interner.contains_value(name.borrow())
153 }
154
155 pub fn object_contains_field(&self, obj: ObjKey, field: FieldKey) -> bool {
157 self.objects_with_field(field)
158 .map(|objs| objs.contains(&obj))
159 .unwrap_or_default()
160 }
161}
162
163impl<ObjKey, Value, FieldKey, Field> Category<ObjKey, Value, FieldKey, Field>
165where
166 ObjKey: Key,
167 FieldKey: Key,
168 Field: Clone + Debug + Ord,
169 Value: FieldValue<FieldKey>,
170{
171 pub fn clean(&mut self) {
174 self.values.retain(|_, fields| fields.should_retain());
175
176 let unused = self
177 .field_interner
178 .keys()
179 .filter(|&field| match self.objects_by_field.get(field) {
180 Some(objects) => objects.is_empty(),
181 None => true,
182 })
183 .collect::<Vec<_>>();
184
185 for field in unused {
186 self.objects_by_field.remove(field);
187 self.field_interner.remove_key(field);
188 }
189 }
190
191 fn object_value_entry(&mut self, obj: ObjKey) -> Option<&mut Value> {
193 self.values.entry(obj).map(|entry| entry.or_default())
194 }
195
196 fn objects_by_field_entry(&mut self, field: FieldKey) -> Option<&mut BTreeSet<ObjKey>> {
198 self.objects_by_field
199 .entry(field)
200 .map(|entry| entry.or_default())
201 }
202
203 pub fn remove_object(&mut self, obj: ObjKey) -> Option<Value> {
206 self.values.remove(obj).inspect(|value| {
207 value.fields().for_each(|field| {
208 self.remove_object_from_field_objects(field, obj);
209 });
210 })
211 }
212
213 fn add_object_to_field_objects(&mut self, field: FieldKey, obj: ObjKey) -> bool {
215 self.objects_by_field_entry(field)
216 .map(|objects| objects.insert(obj))
217 .unwrap_or_default()
218 }
219
220 fn remove_object_from_field_objects(&mut self, field: FieldKey, obj: ObjKey) -> bool {
226 let (is_empty, removed) = self
227 .objects_by_field
228 .get_mut(field)
229 .map(|objects| {
230 let removed = objects.remove(&obj);
231 (objects.is_empty(), removed)
232 })
233 .unwrap_or_default();
234 if is_empty {
235 self.objects_by_field.remove(field);
236 }
237 removed
238 }
239
240 pub fn insert_object_value(&mut self, obj: ObjKey, value: Value) {
242 self.remove_object(obj);
243 value.fields().for_each(|field| {
244 self.objects_by_field
245 .entry(field)
246 .map(|entry| entry.or_default().insert(obj));
247 });
248 self.values.insert(obj, value);
249 }
250
251 pub fn object_fields(&self, obj: ObjKey) -> impl Iterator<Item = FieldKey> {
253 self.values
254 .get(obj)
255 .into_iter()
256 .flat_map(|value| value.fields())
257 }
258
259 pub fn object_field_names(&self, obj: ObjKey) -> impl Iterator<Item = &Field> {
261 self.object_fields(obj).flat_map(|key| self.field_name(key))
262 }
263}
264
265impl<ObjKey, Value, FieldKey, Field> Category<ObjKey, Value, FieldKey, Field>
267where
268 ObjKey: Key,
269 FieldKey: Key,
270 Field: Clone + Debug + Ord,
271 Value: FieldValue<FieldKey> + FieldWithoutSubValue<FieldKey>,
272{
273 pub fn insert_field_name_for_object(&mut self, obj: ObjKey, name: Cow<'_, Field>) -> bool {
275 let field = self.field_key(name);
276 self.insert_field_for_object(obj, field)
277 }
278
279 pub fn insert_field_for_object(&mut self, obj: ObjKey, field: FieldKey) -> bool {
281 self.add_object_to_field_objects(field, obj);
282 self.object_value_entry(obj)
283 .map(|value| value.insert_field(field))
284 .unwrap_or_default()
285 }
286
287 pub fn remove_field_name(&mut self, name: &Field) -> Option<FieldKey> {
290 self.field_key_interned(name).map(|field| {
291 self.remove_field(field);
292 field
293 })
294 }
295
296 pub fn remove_field(&mut self, field: FieldKey) -> Option<Field> {
299 self.objects_by_field
300 .remove(field)
301 .into_iter()
302 .for_each(|objects| {
303 objects.into_iter().for_each(|obj| {
304 self.remove_field_from_object(obj, field);
305 });
306 });
307 self.field_interner.remove_key(field)
308 }
309
310 pub fn remove_field_name_from_object(&mut self, obj: ObjKey, field: &Field) -> bool {
313 self.field_key_interned(field)
314 .map(|field| self.remove_field_from_object(obj, field))
315 .unwrap_or_default()
316 }
317
318 pub fn remove_field_from_object(&mut self, obj: ObjKey, field: FieldKey) -> bool {
321 let retain = self
322 .values
323 .get_mut(obj)
324 .map(|value| {
325 value.remove_field(field);
326 value.should_retain()
327 })
328 .unwrap_or_default();
329
330 if !retain {
331 self.values.remove(obj);
332 }
333
334 self.remove_object_from_field_objects(field, obj)
335 }
336}
337
338impl<ObjKey, Value, SubValue, FieldKey, Field> Category<ObjKey, Value, FieldKey, Field>
340where
341 ObjKey: Key,
342 FieldKey: Key,
343 Field: Clone + Debug + Ord,
344 Value: FieldValue<FieldKey> + FieldWithSubValue<FieldKey, SubValue = SubValue>,
345{
346 pub fn insert_field_name_value_for_object(
349 &mut self,
350 obj: ObjKey,
351 field: Cow<Field>,
352 sub_value: SubValue,
353 ) -> Option<SubValue> {
354 let field = self.field_key(field);
355
356 self.insert_field_value_for_object(obj, field, sub_value)
357 }
358
359 pub fn insert_field_value_for_object(
362 &mut self,
363 obj: ObjKey,
364 field: FieldKey,
365 sub_value: SubValue,
366 ) -> Option<SubValue> {
367 self.add_object_to_field_objects(field, obj);
368 self.object_value_entry(obj)
369 .and_then(|value| value.insert_field_value(field, sub_value))
370 }
371
372 pub fn remove_field_name_values(&mut self, name: &Field) -> Option<FieldKey> {
374 self.field_key_interned(name).map(move |field| {
375 self.remove_field_values(field);
376 field
377 })
378 }
379
380 pub fn remove_field_values(&mut self, field: FieldKey) -> Option<Field> {
382 self.objects_by_field
383 .remove(field)
384 .into_iter()
385 .flat_map(|objects| objects.into_iter())
386 .for_each(|obj| {
387 self.remove_field_value_from_object(obj, field);
388 });
389
390 self.field_interner.remove_key(field)
391 }
392
393 pub fn remove_field_name_value_from_object(
396 &mut self,
397 obj: ObjKey,
398 name: &Field,
399 ) -> Option<SubValue> {
400 self.field_key_interned(name)
401 .and_then(|field| self.remove_field_value_from_object(obj, field))
402 }
403
404 pub fn remove_field_value_from_object(
407 &mut self,
408 obj: ObjKey,
409 field: FieldKey,
410 ) -> Option<SubValue> {
411 self.remove_object_from_field_objects(field, obj);
412
413 let (retain, sub_value) = self
414 .values
415 .get_mut(obj)
416 .map(|value| {
417 let sub_value = value.remove_field_value(field);
418 (value.should_retain(), sub_value)
419 })
420 .unwrap_or_default();
421
422 if !retain {
423 self.values.remove(obj);
424 }
425
426 sub_value
427 }
428
429 pub fn field_value_for_object(&self, obj: ObjKey, field: FieldKey) -> Option<&SubValue> {
431 self.values
432 .get(obj)
433 .and_then(|value| value.field_value(field))
434 }
435
436 pub fn field_name_value_for_object(&self, obj: ObjKey, field: &Field) -> Option<&SubValue> {
438 self.field_key_interned(field)
439 .and_then(|field| self.field_value_for_object(obj, field))
440 }
441}
442
443pub trait FieldValue<FieldKey>: Default {
445 fn should_retain(&self) -> bool;
447
448 fn fields(&self) -> impl Iterator<Item = FieldKey>;
450}
451impl<FieldKey: Key> FieldValue<FieldKey> for FieldKey {
452 fn should_retain(&self) -> bool {
453 self.is_null()
454 }
455 fn fields(&self) -> impl Iterator<Item = FieldKey> {
456 once(*self)
457 }
458}
459impl<FieldKey: Key> FieldValue<FieldKey> for Option<FieldKey> {
460 fn should_retain(&self) -> bool {
461 self.is_some()
462 }
463
464 fn fields(&self) -> impl Iterator<Item = FieldKey> {
465 self.iter().copied()
466 }
467}
468impl<FieldKey: Key> FieldValue<FieldKey> for BTreeSet<FieldKey> {
469 fn should_retain(&self) -> bool {
470 !self.is_empty()
471 }
472
473 fn fields(&self) -> impl Iterator<Item = FieldKey> {
474 self.iter().copied()
475 }
476}
477impl<FieldKey: Key, SubValue> FieldValue<FieldKey> for BTreeMap<FieldKey, SubValue> {
478 fn should_retain(&self) -> bool {
479 !self.is_empty()
480 }
481
482 fn fields(&self) -> impl Iterator<Item = FieldKey> {
483 self.keys().copied()
484 }
485}
486
487pub trait FieldWithoutSubValue<FieldKey: Key> {
490 fn insert_field(&mut self, field: FieldKey) -> bool;
492
493 fn remove_field(&mut self, field: FieldKey) -> bool;
495}
496
497impl<FieldKey: Key> FieldWithoutSubValue<FieldKey> for FieldKey {
498 fn insert_field(&mut self, mut field: FieldKey) -> bool {
499 if self == &field {
500 false
501 } else {
502 std::mem::swap(self, &mut field);
503 true
504 }
505 }
506 fn remove_field(&mut self, field: FieldKey) -> bool {
507 if self == &field {
508 std::mem::take(self);
509 true
510 } else {
511 false
512 }
513 }
514}
515impl<FieldKey: Key> FieldWithoutSubValue<FieldKey> for Option<FieldKey> {
516 fn insert_field(&mut self, field: FieldKey) -> bool {
517 if self == &Some(field) {
518 false
519 } else {
520 self.replace(field);
521 true
522 }
523 }
524
525 fn remove_field(&mut self, field: FieldKey) -> bool {
526 if self.as_ref() == Some(&field) {
527 self.take().is_some()
528 } else {
529 false
530 }
531 }
532}
533impl<FieldKey: Key> FieldWithoutSubValue<FieldKey> for BTreeSet<FieldKey> {
534 fn insert_field(&mut self, field: FieldKey) -> bool {
535 self.insert(field)
536 }
537
538 fn remove_field(&mut self, field: FieldKey) -> bool {
539 self.remove(&field)
540 }
541}
542impl<FieldKey: Key, SubValue: Default> FieldWithoutSubValue<FieldKey>
543 for BTreeMap<FieldKey, SubValue>
544{
545 fn insert_field(&mut self, field: FieldKey) -> bool {
546 self.insert(field, SubValue::default()).is_none()
547 }
548
549 fn remove_field(&mut self, field: FieldKey) -> bool {
550 self.remove(&field).is_some()
551 }
552}
553
554pub trait FieldWithSubValue<FieldKey: Key> {
556 type SubValue;
557
558 fn field_value(&self, field: FieldKey) -> Option<&Self::SubValue>;
560
561 fn insert_field_value(
563 &mut self,
564 field: FieldKey,
565 value: Self::SubValue,
566 ) -> Option<Self::SubValue>;
567
568 fn remove_field_value(&mut self, field: FieldKey) -> Option<Self::SubValue>;
570}
571impl<FieldKey: Key, SubValue> FieldWithSubValue<FieldKey> for BTreeMap<FieldKey, SubValue> {
572 type SubValue = SubValue;
573
574 fn field_value(&self, field: FieldKey) -> Option<&SubValue> {
575 self.get(&field)
576 }
577
578 fn insert_field_value(&mut self, field: FieldKey, value: SubValue) -> Option<SubValue> {
579 self.insert(field, value)
580 }
581
582 fn remove_field_value(&mut self, field: FieldKey) -> Option<SubValue> {
583 self.remove(&field)
584 }
585}
586
587impl<ObjKey, FieldKey, Field> Category<ObjKey, FieldKey, FieldKey, Field>
589where
590 ObjKey: Key,
591 FieldKey: Key,
592 Field: Clone + Debug + Ord,
593{
594 pub fn value_name_of_object(&self, obj: ObjKey) -> Option<&Field> {
596 let key = self.object_value(obj)?;
597 self.field_name(*key)
598 }
599
600 pub fn set_value_name_of_object(&mut self, obj: ObjKey, value: Option<Cow<Field>>) {
602 if let Some(field) = value {
603 let field = self.field_key(field);
604 self.insert_object_value(obj, field);
605 } else {
606 self.remove_object(obj);
607 }
608 }
609}
610
611impl<ObjKey, FieldKey, Field> Category<ObjKey, Option<FieldKey>, FieldKey, Field>
613where
614 ObjKey: Key,
615 FieldKey: Key,
616 Field: Clone + Debug + Ord,
617{
618 pub fn value_name_of_object(&self, obj: ObjKey) -> Option<&Field> {
620 let key = self.object_value(obj)?.as_ref()?;
621 self.field_name(*key)
622 }
623
624 pub fn set_value_name_of_object(&mut self, obj: ObjKey, value: Option<Cow<Field>>) {
626 if let Some(field) = value {
627 let field = self.field_key(field);
628 self.insert_object_value(obj, Some(field));
629 } else {
630 self.remove_object(obj);
631 }
632 }
633}
634
635impl<ObjKey, FieldKey, Field> Category<ObjKey, BTreeSet<FieldKey>, FieldKey, Field>
637where
638 ObjKey: Key,
639 FieldKey: Key,
640 Field: Clone + Debug + Ord,
641{
642 pub fn named_value_of_object(&self, obj: ObjKey) -> BTreeSet<&Field> {
644 self.object_value(obj)
645 .into_iter()
646 .flat_map(|set| set.iter())
647 .flat_map(|key| self.field_name(*key))
648 .collect()
649 }
650}
651
652impl<ObjKey, FieldKey, Field, SubValue>
654 Category<ObjKey, BTreeMap<FieldKey, SubValue>, FieldKey, Field>
655where
656 ObjKey: Key,
657 FieldKey: Key,
658 Field: Clone + Debug + Ord,
659{
660 pub fn named_value_of_object(&self, obj: ObjKey) -> BTreeMap<&Field, &SubValue> {
662 self.object_value(obj)
663 .into_iter()
664 .flat_map(|mapping| mapping.iter())
665 .flat_map(|(key, value)| self.field_name(*key).map(|field| (field, value)))
666 .collect()
667 }
668}