1#![allow(missing_docs, reason = "False positives")]
4
5use alloc::{collections::VecDeque, vec::Vec};
6use core::{
7 cmp::Ordering,
8 hash::{BuildHasher, Hash},
9 marker::PhantomData,
10};
11
12use hashbrown::{HashMap, HashSet};
13
14#[cfg(feature = "rkyv")]
15use rkyv::{Archive, Deserialize, Serialize};
16
17#[cfg(feature = "serde")]
18use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
19
20use crate::{
21 ActivePathWeave, ActiveSingularWeave, BookmarkableWeave, DeduplicatableContents,
22 DiscreteContentResult, DiscreteContents, DiscreteWeave, IndependentContents, IndependentWeave,
23 MetadataWeave, Node, SemiIndependentWeave, SortableBookmarkableWeave, SortableWeave, Weave,
24 dependent, independent,
25};
26
27#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
32#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
33#[must_use]
34pub struct LoggedWeave<W, K, N, T, M>
35where
36 W: Weave<K, N, T>,
37 K: Hash + Copy + Eq + Ord,
38 N: Node<K, T>,
39{
40 pub weave: W,
44
45 pub actions: VecDeque<WeaveAction<K, N, T, M>>,
47}
48
49impl<W, K, N, T, M> AsRef<W> for LoggedWeave<W, K, N, T, M>
50where
51 W: Weave<K, N, T>,
52 K: Hash + Copy + Eq + Ord,
53 N: Node<K, T>,
54{
55 #[inline]
56 fn as_ref(&self) -> &W {
57 &self.weave
58 }
59}
60
61impl<W, K, N, T, M> From<W> for LoggedWeave<W, K, N, T, M>
62where
63 W: Weave<K, N, T>,
64 K: Hash + Copy + Eq + Ord,
65 N: Node<K, T>,
66{
67 #[inline]
68 fn from(value: W) -> Self {
69 Self {
70 weave: value,
71 actions: VecDeque::new(),
72 }
73 }
74}
75
76impl<W, K, N, T, M> LoggedWeave<W, K, N, T, M>
77where
78 W: Weave<K, N, T>,
79 K: Hash + Copy + Eq + Ord,
80 N: Node<K, T>,
81{
82 #[inline]
84 pub fn with_capacity(weave: W, capacity: usize) -> Self {
85 Self {
86 actions: VecDeque::with_capacity(capacity),
87 weave,
88 }
89 }
90 #[inline]
92 pub fn into_weave(self) -> W {
93 self.weave
94 }
95 #[inline]
97 pub const fn as_weave(&self) -> &W {
98 &self.weave
99 }
100 #[inline]
102 pub const fn as_actions(&self) -> &VecDeque<WeaveAction<K, N, T, M>> {
103 &self.actions
104 }
105 #[inline]
107 pub fn clear_actions(&mut self) {
108 self.actions.clear();
109 }
110 pub fn count_actions(&self) -> WeaveActionCount {
112 let mut count = WeaveActionCount::new();
113
114 for action in &self.actions {
115 count.increment(action);
116 }
117
118 count
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
128#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
129#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
130#[allow(clippy::doc_paragraphs_missing_punctuation, reason = "False positive")]
131#[non_exhaustive]
132#[must_use]
133pub enum WeaveAction<K, N, T, M>
134where
135 K: Hash + Copy + Eq + Ord,
136 N: Node<K, T>,
137{
138 Insert(N),
140 SetActive { id: K, value: bool },
142 SetBookmarked { id: K, value: bool },
144 Remove(K),
146 Clear,
148 SetMetadata(M),
150 SetChildOrdering { parent: Option<K>, children: Vec<K> },
152 SetBookmarkOrdering(Vec<K>),
154 SetActivePath(Vec<K>),
156 MoveTo { id: K, new_parents: Vec<K> },
158 SetContents { id: K, contents: T },
160 Split { id: K, at: usize, new_id: K },
162 MergeWithParent(K),
164}
165
166#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
170#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
171#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
172#[must_use]
173pub struct CountedWeave<W, K, N, T>
174where
175 W: Weave<K, N, T>,
176 K: Hash + Copy + Eq + Ord,
177 N: Node<K, T>,
178{
179 pub weave: W,
183
184 pub count: WeaveActionCount,
186
187 _phantom_k: PhantomData<K>,
188 _phantom_n: PhantomData<N>,
189 _phantom_t: PhantomData<T>,
190}
191
192impl<W, K, N, T> AsRef<W> for CountedWeave<W, K, N, T>
193where
194 W: Weave<K, N, T>,
195 K: Hash + Copy + Eq + Ord,
196 N: Node<K, T>,
197{
198 #[inline]
199 fn as_ref(&self) -> &W {
200 &self.weave
201 }
202}
203
204impl<W, K, N, T> From<W> for CountedWeave<W, K, N, T>
205where
206 W: Weave<K, N, T>,
207 K: Hash + Copy + Eq + Ord,
208 N: Node<K, T>,
209{
210 #[inline]
211 fn from(value: W) -> Self {
212 Self {
213 weave: value,
214 count: WeaveActionCount::default(),
215 _phantom_k: PhantomData,
216 _phantom_n: PhantomData,
217 _phantom_t: PhantomData,
218 }
219 }
220}
221
222impl<W, K, N, T> CountedWeave<W, K, N, T>
223where
224 W: Weave<K, N, T>,
225 K: Hash + Copy + Eq + Ord,
226 N: Node<K, T>,
227{
228 #[inline]
230 pub const fn new(weave: W, count: WeaveActionCount) -> Self {
231 Self {
232 weave,
233 count,
234 _phantom_k: PhantomData,
235 _phantom_n: PhantomData,
236 _phantom_t: PhantomData,
237 }
238 }
239 pub fn from_weave(weave: W) -> Self {
241 Self::new(weave, WeaveActionCount::new())
242 }
243 #[inline]
245 pub fn into_weave(self) -> W {
246 self.weave
247 }
248 #[inline]
250 pub const fn as_weave(&self) -> &W {
251 &self.weave
252 }
253 #[inline]
255 pub const fn as_count(&self) -> &WeaveActionCount {
256 &self.count
257 }
258 #[inline]
260 pub fn reset_count(&mut self) {
261 self.count.reset();
262 }
263}
264
265#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
270#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
271#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
272#[allow(clippy::doc_paragraphs_missing_punctuation, reason = "False positive")]
273#[non_exhaustive]
274#[must_use]
275pub struct WeaveActionCount {
276 pub insert: usize,
278 pub set_active: usize,
280 pub set_bookmarked: usize,
282 pub remove: usize,
284 pub clear: usize,
286 pub metadata_mut: usize,
288 pub sort_children: usize,
290 pub sort_roots: usize,
292 pub sort_bookmarks: usize,
294 pub set_active_path: usize,
296 pub move_to: usize,
298 pub get_contents_mut: usize,
300 pub split: usize,
302 pub merge_with_parent: usize,
304 pub other: usize,
306}
307
308impl WeaveActionCount {
309 #[inline]
311 pub fn new() -> Self {
312 Self::default()
313 }
314 #[inline]
316 pub fn reset(&mut self) {
317 *self = Self::default();
318 }
319 #[must_use]
321 pub const fn total_count(&self) -> usize {
322 self.insert
323 .saturating_add(self.set_active)
324 .saturating_add(self.set_bookmarked)
325 .saturating_add(self.remove)
326 .saturating_add(self.clear)
327 .saturating_add(self.metadata_mut)
328 .saturating_add(self.sort_children)
329 .saturating_add(self.sort_roots)
330 .saturating_add(self.sort_bookmarks)
331 .saturating_add(self.set_active_path)
332 .saturating_add(self.move_to)
333 .saturating_add(self.get_contents_mut)
334 .saturating_add(self.split)
335 .saturating_add(self.merge_with_parent)
336 .saturating_add(self.other)
337 }
338 pub const fn increment<K, N, T, M>(&mut self, action: &WeaveAction<K, N, T, M>)
340 where
341 K: Hash + Copy + Eq + Ord,
342 N: Node<K, T>,
343 {
344 match action {
345 WeaveAction::Insert(_node) => self.insert = self.insert.saturating_add(1),
346 WeaveAction::SetActive { .. } => {
347 self.set_active = self.set_active.saturating_add(1);
348 }
349 WeaveAction::SetBookmarked { .. } => {
350 self.set_bookmarked = self.set_bookmarked.saturating_add(1);
351 }
352 WeaveAction::Remove(_id) => self.remove = self.remove.saturating_add(1),
353 WeaveAction::Clear => {
354 self.clear = self.clear.saturating_add(1);
355 }
356 WeaveAction::SetMetadata(_metadata) => {
357 self.metadata_mut = self.metadata_mut.saturating_add(1);
358 }
359 WeaveAction::SetChildOrdering { parent, .. } => match parent {
360 Some(_id) => self.sort_children = self.sort_children.saturating_add(1),
361 None => self.sort_roots = self.sort_roots.saturating_add(1),
362 },
363 WeaveAction::SetBookmarkOrdering(_ids) => {
364 self.sort_bookmarks = self.sort_bookmarks.saturating_add(1);
365 }
366 WeaveAction::SetActivePath(_) => {
367 self.set_active_path = self.set_active_path.saturating_add(1);
368 }
369 WeaveAction::MoveTo { .. } => self.move_to = self.move_to.saturating_add(1),
370 WeaveAction::SetContents { .. } => {
371 self.get_contents_mut = self.get_contents_mut.saturating_add(1);
372 }
373 WeaveAction::Split { .. } => self.split = self.split.saturating_add(1),
374 WeaveAction::MergeWithParent(_id) => {
375 self.merge_with_parent = self.merge_with_parent.saturating_add(1);
376 }
377 }
378 }
379 pub const fn decrement<K, N, T, M>(&mut self, action: &WeaveAction<K, N, T, M>)
381 where
382 K: Hash + Copy + Eq + Ord,
383 N: Node<K, T>,
384 {
385 match action {
386 WeaveAction::Insert(_node) => self.insert = self.insert.saturating_sub(1),
387 WeaveAction::SetActive { .. } => {
388 self.set_active = self.set_active.saturating_sub(1);
389 }
390 WeaveAction::SetBookmarked { .. } => {
391 self.set_bookmarked = self.set_bookmarked.saturating_sub(1);
392 }
393 WeaveAction::Remove(_id) => self.remove = self.remove.saturating_sub(1),
394 WeaveAction::Clear => {
395 self.clear = self.clear.saturating_sub(1);
396 }
397 WeaveAction::SetMetadata(_metadata) => {
398 self.metadata_mut = self.metadata_mut.saturating_sub(1);
399 }
400 WeaveAction::SetChildOrdering { parent, .. } => match parent {
401 Some(_id) => self.sort_children = self.sort_children.saturating_sub(1),
402 None => self.sort_roots = self.sort_roots.saturating_sub(1),
403 },
404 WeaveAction::SetBookmarkOrdering(_ids) => {
405 self.sort_bookmarks = self.sort_bookmarks.saturating_sub(1);
406 }
407 WeaveAction::SetActivePath(_) => {
408 self.set_active_path = self.set_active_path.saturating_sub(1);
409 }
410 WeaveAction::MoveTo { .. } => self.move_to = self.move_to.saturating_sub(1),
411 WeaveAction::SetContents { .. } => {
412 self.get_contents_mut = self.get_contents_mut.saturating_sub(1);
413 }
414 WeaveAction::Split { .. } => self.split = self.split.saturating_sub(1),
415 WeaveAction::MergeWithParent(_id) => {
416 self.merge_with_parent = self.merge_with_parent.saturating_sub(1);
417 }
418 }
419 }
420}
421
422pub trait ActionableWeave<K, N, T, M, S>
424where
425 K: Hash + Copy + Eq + Ord,
426 N: Node<K, T>,
427 S: BuildHasher + Default + Clone,
428{
429 fn apply(&mut self, action: WeaveAction<K, N, T, M>);
435}
436
437impl<K, T, M, S> ActionableWeave<K, dependent::DependentNode<K, T, S>, T, M, S>
530 for dependent::DependentWeave<K, T, M, S>
531where
532 K: Hash + Copy + Eq + Ord,
533 T: IndependentContents + DiscreteContents,
534 S: BuildHasher + Default + Clone,
535{
536 #[allow(clippy::panic, reason = "Necessary due to API shape")]
537 fn apply(&mut self, action: WeaveAction<K, dependent::DependentNode<K, T, S>, T, M>) {
538 match action {
539 WeaveAction::Insert(node) => {
540 assert!(self.insert(node), "Failed to apply Weave action");
541 }
542 WeaveAction::SetActive { id, value } => {
543 assert!(self.set_active(&id, value), "Failed to apply Weave action");
544 }
545 WeaveAction::SetBookmarked { id, value } => {
546 assert!(
547 self.set_bookmarked(&id, value),
548 "Failed to apply Weave action"
549 );
550 }
551 WeaveAction::Remove(id) => {
552 assert!(self.remove(&id).is_some(), "Failed to apply Weave action");
553 }
554 WeaveAction::Clear => self.clear(),
555 WeaveAction::SetMetadata(metadata) => {
556 self.metadata_mut(|m| *m = metadata);
557 }
558 WeaveAction::SetChildOrdering { parent, children } => {
559 let mut id_mapping =
560 HashMap::with_capacity_and_hasher(children.len(), S::default());
561 id_mapping.extend(
562 children
563 .into_iter()
564 .enumerate()
565 .map(|(index, id)| (id, index)),
566 );
567
568 match parent {
569 Some(id) => {
570 assert!(
571 self.sort_children_by_id(&id, |a, b| {
572 id_mapping[a].cmp(&id_mapping[b])
573 }),
574 "Failed to apply Weave action"
575 );
576 }
577 None => {
578 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
579 }
580 }
581 }
582 WeaveAction::SetBookmarkOrdering(ids) => {
583 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
584 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
585
586 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
587 }
588 WeaveAction::SetActivePath(_) => {
589 panic!("Weave does not implement set_active_path()");
590 }
591 WeaveAction::MoveTo { .. } => {
592 panic!("Weave does not implement move_to()");
593 }
594 WeaveAction::SetContents { id, contents } => {
595 assert!(
596 self.get_contents_mut(&id, |c| *c = contents).is_some(),
597 "Failed to apply Weave action"
598 );
599 }
600 WeaveAction::Split { id, at, new_id } => {
601 assert!(self.split(&id, at, new_id), "Failed to apply Weave action");
602 }
603 WeaveAction::MergeWithParent(id) => assert!(
604 self.merge_with_parent(&id).is_some(),
605 "Failed to apply Weave action"
606 ),
607 }
608 }
609}
610
611impl<K, T, M, S> ActionableWeave<K, independent::IndependentNode<K, T, S>, T, M, S>
613 for independent::IndependentWeave<K, T, M, S>
614where
615 K: Hash + Copy + Eq + Ord,
616 T: IndependentContents + DiscreteContents,
617 S: BuildHasher + Default + Clone,
618{
619 fn apply(&mut self, action: WeaveAction<K, independent::IndependentNode<K, T, S>, T, M>) {
620 match action {
621 WeaveAction::Insert(node) => {
622 assert!(self.insert(node), "Failed to apply Weave action");
623 }
624 WeaveAction::SetActive { id, value } => {
625 assert!(self.set_active(&id, value), "Failed to apply Weave action");
626 }
627 WeaveAction::SetBookmarked { id, value } => {
628 assert!(
629 self.set_bookmarked(&id, value),
630 "Failed to apply Weave action"
631 );
632 }
633 WeaveAction::Remove(id) => {
634 assert!(self.remove(&id).is_some(), "Failed to apply Weave action");
635 }
636 WeaveAction::Clear => self.clear(),
637 WeaveAction::SetMetadata(metadata) => {
638 self.metadata_mut(|m| *m = metadata);
639 }
640 WeaveAction::SetChildOrdering { parent, children } => {
641 let mut id_mapping =
642 HashMap::with_capacity_and_hasher(children.len(), S::default());
643 id_mapping.extend(
644 children
645 .into_iter()
646 .enumerate()
647 .map(|(index, id)| (id, index)),
648 );
649
650 match parent {
651 Some(id) => {
652 assert!(
653 self.sort_children_by_id(&id, |a, b| {
654 id_mapping[a].cmp(&id_mapping[b])
655 }),
656 "Failed to apply Weave action"
657 );
658 }
659 None => {
660 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
661 }
662 }
663 }
664 WeaveAction::SetBookmarkOrdering(ids) => {
665 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
666 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
667
668 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
669 }
670 WeaveAction::SetActivePath(active) => {
671 self.set_active_path(active.into_iter());
672 }
673 WeaveAction::MoveTo { id, new_parents } => assert!(
674 self.move_to(&id, &new_parents),
675 "Failed to apply Weave action"
676 ),
677 WeaveAction::SetContents { id, contents } => {
678 assert!(
679 self.get_contents_mut(&id, |c| *c = contents).is_some(),
680 "Failed to apply Weave action"
681 );
682 }
683 WeaveAction::Split { id, at, new_id } => {
684 assert!(self.split(&id, at, new_id), "Failed to apply Weave action");
685 }
686 WeaveAction::MergeWithParent(id) => assert!(
687 self.merge_with_parent(&id).is_some(),
688 "Failed to apply Weave action"
689 ),
690 }
691 }
692}
693
694impl<W, K, N, T, M> Weave<K, N, T> for LoggedWeave<W, K, N, T, M>
695where
696 W: Weave<K, N, T>,
697 K: Hash + Copy + Eq + Ord,
698 N: Node<K, T> + Clone,
699{
700 type Nodes = W::Nodes;
701 type Roots = W::Roots;
702
703 #[inline]
704 fn len(&self) -> usize {
705 self.weave.len()
706 }
707 #[inline]
708 fn is_empty(&self) -> bool {
709 self.weave.is_empty()
710 }
711 #[inline]
712 fn nodes(&self) -> &Self::Nodes {
713 self.weave.nodes()
714 }
715 #[inline]
716 fn roots(&self) -> &Self::Roots {
717 self.weave.roots()
718 }
719 #[inline]
720 fn contains(&self, id: &K) -> bool {
721 self.weave.contains(id)
722 }
723 #[inline]
724 fn contains_active(&self, id: &K) -> bool {
725 self.weave.contains_active(id)
726 }
727 #[inline]
728 fn get(&self, id: &K) -> Option<&N> {
729 self.weave.get(id)
730 }
731 #[inline]
732 fn get_parents(&self, id: &K) -> Option<&N::From> {
733 self.weave.get_parents(id)
734 }
735 #[inline]
736 fn get_children(&self, id: &K) -> Option<&N::To> {
737 self.weave.get_children(id)
738 }
739 #[inline]
740 fn get_contents(&self, id: &K) -> Option<&T> {
741 self.weave.get_contents(id)
742 }
743 #[inline]
744 fn get_ordered_identifiers(&mut self, output: &mut Vec<K>) {
745 self.weave.get_ordered_identifiers(output);
746 }
747 #[inline]
748 fn get_ordered_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
749 self.weave.get_ordered_identifiers_from(id, output);
750 }
751 #[inline]
752 fn get_active_path(&mut self, output: &mut Vec<K>) {
753 self.weave.get_active_path(output);
754 }
755 #[inline]
756 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
757 self.weave.get_path_from(id, output);
758 }
759 fn insert(&mut self, node: N) -> bool {
760 if self.weave.insert(node.clone()) {
761 self.actions.push_back(WeaveAction::Insert(node));
762 true
763 } else {
764 false
765 }
766 }
767 fn set_active(&mut self, id: &K, value: bool) -> bool {
768 if self.weave.set_active(id, value) {
769 self.actions
770 .push_back(WeaveAction::SetActive { id: *id, value });
771 true
772 } else {
773 false
774 }
775 }
776 fn remove(&mut self, id: &K) -> Option<N> {
777 if let Some(removed) = self.weave.remove(id) {
778 self.actions.push_back(WeaveAction::Remove(*id));
779 Some(removed)
780 } else {
781 None
782 }
783 }
784 fn remove_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
785 if self.weave.remove_tracked(id, on_removal) {
786 self.actions.push_back(WeaveAction::Remove(*id));
787 true
788 } else {
789 false
790 }
791 }
792 fn clear(&mut self) {
793 self.weave.clear();
794 self.actions.push_back(WeaveAction::Clear);
795 }
796}
797
798impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for LoggedWeave<W, K, N, T, M>
799where
800 W: MetadataWeave<K, N, T, M>,
801 K: Hash + Copy + Eq + Ord,
802 N: Node<K, T> + Clone,
803 M: Clone,
804{
805 #[inline]
806 fn metadata(&self) -> &M {
807 self.weave.metadata()
808 }
809 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
810 self.weave.metadata_mut(|metadata| {
811 let output = callback(metadata);
812
813 self.actions
814 .push_back(WeaveAction::SetMetadata(metadata.clone()));
815
816 output
817 })
818 }
819}
820
821impl<W, K, N, T, M> BookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
822where
823 W: BookmarkableWeave<K, N, T>,
824 K: Hash + Copy + Eq + Ord,
825 N: Node<K, T> + Clone,
826{
827 type Bookmarks = W::Bookmarks;
828
829 #[inline]
830 fn bookmarks(&self) -> &Self::Bookmarks {
831 self.weave.bookmarks()
832 }
833 #[inline]
834 fn contains_bookmark(&self, id: &K) -> bool {
835 self.weave.contains_bookmark(id)
836 }
837 fn set_bookmarked(&mut self, id: &K, value: bool) -> bool {
838 if self.weave.set_bookmarked(id, value) {
839 self.actions
840 .push_back(WeaveAction::SetBookmarked { id: *id, value });
841 true
842 } else {
843 false
844 }
845 }
846}
847
848impl<W, K, N, T, M> SortableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
849where
850 W: SortableWeave<K, N, T>,
851 K: Hash + Copy + Eq + Ord,
852 N: Node<K, T> + Clone,
853 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
854 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
855{
856 fn sort_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
857 if self.weave.sort_children_by(id, cmp) {
858 self.actions.push_back(WeaveAction::SetChildOrdering {
859 parent: Some(*id),
860 children: self
861 .weave
862 .get_children(id)
863 .unwrap()
864 .into_iter()
865 .copied()
866 .collect(),
867 });
868 true
869 } else {
870 false
871 }
872 }
873 fn sort_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
874 if self.weave.sort_children_by_id(id, cmp) {
875 self.actions.push_back(WeaveAction::SetChildOrdering {
876 parent: Some(*id),
877 children: self
878 .weave
879 .get_children(id)
880 .unwrap()
881 .into_iter()
882 .copied()
883 .collect(),
884 });
885 true
886 } else {
887 false
888 }
889 }
890 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
891 self.weave.sort_roots_by(cmp);
892 self.actions.push_back(WeaveAction::SetChildOrdering {
893 parent: None,
894 children: self.weave.roots().into_iter().copied().collect(),
895 });
896 }
897 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
898 self.weave.sort_roots_by_id(cmp);
899 self.actions.push_back(WeaveAction::SetChildOrdering {
900 parent: None,
901 children: self.weave.roots().into_iter().copied().collect(),
902 });
903 }
904}
905
906impl<W, K, N, T, M> SortableBookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
907where
908 W: SortableBookmarkableWeave<K, N, T>,
909 K: Hash + Copy + Eq + Ord,
910 N: Node<K, T> + Clone,
911 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
912 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
913 for<'a> &'a W::Bookmarks: IntoIterator<Item = &'a K>,
914{
915 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
916 self.weave.sort_bookmarks_by(cmp);
917 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
918 self.weave.bookmarks().into_iter().copied().collect(),
919 ));
920 }
921 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
922 self.weave.sort_bookmarks_by_id(cmp);
923 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
924 self.weave.bookmarks().into_iter().copied().collect(),
925 ));
926 }
927}
928
929impl<W, K, N, T, M> ActiveSingularWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
930where
931 W: ActiveSingularWeave<K, N, T>,
932 K: Hash + Copy + Eq + Ord,
933 N: Node<K, T> + Clone,
934{
935 #[inline]
936 fn active(&self) -> Option<K> {
937 self.weave.active()
938 }
939}
940
941impl<W, K, N, T, M> ActivePathWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
942where
943 W: ActivePathWeave<K, N, T>,
944 K: Hash + Copy + Eq + Ord,
945 N: Node<K, T> + Clone,
946{
947 type Active = W::Active;
948
949 #[inline]
950 fn active(&self) -> &Self::Active {
951 self.weave.active()
952 }
953 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
954 let active: Vec<K> = active.collect();
955
956 self.weave.set_active_path(active.iter().copied());
957 self.actions.push_back(WeaveAction::SetActivePath(active));
958 }
959}
960
961impl<W, K, N, T, M> IndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
962where
963 W: IndependentWeave<K, N, T>,
964 K: Hash + Copy + Eq + Ord,
965 N: Node<K, T> + Clone,
966 T: IndependentContents + Clone,
967{
968 fn move_to(&mut self, id: &K, new_parents: &[K]) -> bool {
969 if self.weave.move_to(id, new_parents) {
970 self.actions.push_back(WeaveAction::MoveTo {
971 id: *id,
972 new_parents: new_parents.to_vec(),
973 });
974 true
975 } else {
976 false
977 }
978 }
979}
980
981impl<W, K, N, T, M> SemiIndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
982where
983 W: SemiIndependentWeave<K, N, T>,
984 K: Hash + Copy + Eq + Ord,
985 N: Node<K, T> + Clone,
986 T: IndependentContents + Clone,
987{
988 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
989 self.weave
990 .get_contents_mut(id, |contents| (callback(contents), contents.clone()))
991 .map(|(output, contents)| {
992 self.actions
993 .push_back(WeaveAction::SetContents { id: *id, contents });
994
995 output
996 })
997 }
998}
999
1000impl<W, K, N, T, M> DiscreteWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
1001where
1002 W: DiscreteWeave<K, N, T>,
1003 K: Hash + Copy + Eq + Ord,
1004 N: Node<K, T> + Clone,
1005 T: DiscreteContents,
1006{
1007 fn split(&mut self, id: &K, at: usize, new_id: K) -> bool {
1008 if self.weave.split(id, at, new_id) {
1009 self.actions.push_back(WeaveAction::Split {
1010 id: *id,
1011 at,
1012 new_id,
1013 });
1014 true
1015 } else {
1016 false
1017 }
1018 }
1019 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1020 match self.weave.merge_with_parent(id) {
1021 Some(new_id) => {
1022 self.actions.push_back(WeaveAction::MergeWithParent(*id));
1023 Some(new_id)
1024 }
1025 None => None,
1026 }
1027 }
1028}
1029
1030impl<W, K, N, T> Weave<K, N, T> for CountedWeave<W, K, N, T>
1031where
1032 W: Weave<K, N, T>,
1033 K: Hash + Copy + Eq + Ord,
1034 N: Node<K, T>,
1035{
1036 type Nodes = W::Nodes;
1037 type Roots = W::Roots;
1038
1039 #[inline]
1040 fn len(&self) -> usize {
1041 self.weave.len()
1042 }
1043 #[inline]
1044 fn is_empty(&self) -> bool {
1045 self.weave.is_empty()
1046 }
1047 #[inline]
1048 fn nodes(&self) -> &Self::Nodes {
1049 self.weave.nodes()
1050 }
1051 #[inline]
1052 fn roots(&self) -> &Self::Roots {
1053 self.weave.roots()
1054 }
1055 #[inline]
1056 fn contains(&self, id: &K) -> bool {
1057 self.weave.contains(id)
1058 }
1059 #[inline]
1060 fn contains_active(&self, id: &K) -> bool {
1061 self.weave.contains_active(id)
1062 }
1063 #[inline]
1064 fn get(&self, id: &K) -> Option<&N> {
1065 self.weave.get(id)
1066 }
1067 #[inline]
1068 fn get_parents(&self, id: &K) -> Option<&N::From> {
1069 self.weave.get_parents(id)
1070 }
1071 #[inline]
1072 fn get_children(&self, id: &K) -> Option<&N::To> {
1073 self.weave.get_children(id)
1074 }
1075 #[inline]
1076 fn get_contents(&self, id: &K) -> Option<&T> {
1077 self.weave.get_contents(id)
1078 }
1079 #[inline]
1080 fn get_ordered_identifiers(&mut self, output: &mut Vec<K>) {
1081 self.weave.get_ordered_identifiers(output);
1082 }
1083 #[inline]
1084 fn get_ordered_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
1085 self.weave.get_ordered_identifiers_from(id, output);
1086 }
1087 #[inline]
1088 fn get_active_path(&mut self, output: &mut Vec<K>) {
1089 self.weave.get_active_path(output);
1090 }
1091 #[inline]
1092 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
1093 self.weave.get_path_from(id, output);
1094 }
1095 #[inline]
1096 fn insert(&mut self, node: N) -> bool {
1097 if self.weave.insert(node) {
1098 self.count.insert = self.count.insert.saturating_add(1);
1099 true
1100 } else {
1101 false
1102 }
1103 }
1104 #[inline]
1105 fn set_active(&mut self, id: &K, value: bool) -> bool {
1106 if self.weave.set_active(id, value) {
1107 self.count.set_active = self.count.set_active.saturating_add(1);
1108 true
1109 } else {
1110 false
1111 }
1112 }
1113 #[inline]
1114 fn remove(&mut self, id: &K) -> Option<N> {
1115 if let Some(removed) = self.weave.remove(id) {
1116 self.count.remove = self.count.remove.saturating_add(1);
1117 Some(removed)
1118 } else {
1119 None
1120 }
1121 }
1122 #[inline]
1123 fn remove_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
1124 if self.weave.remove_tracked(id, on_removal) {
1125 self.count.remove = self.count.remove.saturating_add(1);
1126 true
1127 } else {
1128 false
1129 }
1130 }
1131 #[inline]
1132 fn clear(&mut self) {
1133 self.weave.clear();
1134 self.count.clear = self.count.clear.saturating_add(1);
1135 }
1136}
1137
1138impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for CountedWeave<W, K, N, T>
1139where
1140 W: MetadataWeave<K, N, T, M>,
1141 K: Hash + Copy + Eq + Ord,
1142 N: Node<K, T>,
1143{
1144 #[inline]
1145 fn metadata(&self) -> &M {
1146 self.weave.metadata()
1147 }
1148 #[inline]
1149 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
1150 self.weave.metadata_mut(|metadata| {
1151 let output = callback(metadata);
1152 self.count.metadata_mut = self.count.metadata_mut.saturating_add(1);
1153 output
1154 })
1155 }
1156}
1157
1158impl<W, K, N, T> BookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1159where
1160 W: BookmarkableWeave<K, N, T>,
1161 K: Hash + Copy + Eq + Ord,
1162 N: Node<K, T>,
1163{
1164 type Bookmarks = W::Bookmarks;
1165
1166 #[inline]
1167 fn bookmarks(&self) -> &Self::Bookmarks {
1168 self.weave.bookmarks()
1169 }
1170 #[inline]
1171 fn contains_bookmark(&self, id: &K) -> bool {
1172 self.weave.contains_bookmark(id)
1173 }
1174 #[inline]
1175 fn set_bookmarked(&mut self, id: &K, value: bool) -> bool {
1176 if self.weave.set_bookmarked(id, value) {
1177 self.count.set_bookmarked = self.count.set_bookmarked.saturating_add(1);
1178 true
1179 } else {
1180 false
1181 }
1182 }
1183}
1184
1185impl<W, K, N, T> SortableWeave<K, N, T> for CountedWeave<W, K, N, T>
1186where
1187 W: SortableWeave<K, N, T>,
1188 K: Hash + Copy + Eq + Ord,
1189 N: Node<K, T>,
1190{
1191 #[inline]
1192 fn sort_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
1193 if self.weave.sort_children_by(id, cmp) {
1194 self.count.sort_children = self.count.sort_children.saturating_add(1);
1195 true
1196 } else {
1197 false
1198 }
1199 }
1200 #[inline]
1201 fn sort_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
1202 if self.weave.sort_children_by_id(id, cmp) {
1203 self.count.sort_children = self.count.sort_children.saturating_add(1);
1204 true
1205 } else {
1206 false
1207 }
1208 }
1209 #[inline]
1210 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1211 self.weave.sort_roots_by(cmp);
1212 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1213 }
1214 #[inline]
1215 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1216 self.weave.sort_roots_by_id(cmp);
1217 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1218 }
1219}
1220
1221impl<W, K, N, T> SortableBookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1222where
1223 W: SortableBookmarkableWeave<K, N, T>,
1224 K: Hash + Copy + Eq + Ord,
1225 N: Node<K, T>,
1226{
1227 #[inline]
1228 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1229 self.weave.sort_bookmarks_by(cmp);
1230 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1231 }
1232 #[inline]
1233 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1234 self.weave.sort_bookmarks_by_id(cmp);
1235 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1236 }
1237}
1238
1239impl<W, K, N, T> ActiveSingularWeave<K, N, T> for CountedWeave<W, K, N, T>
1240where
1241 W: ActiveSingularWeave<K, N, T>,
1242 K: Hash + Copy + Eq + Ord,
1243 N: Node<K, T>,
1244{
1245 #[inline]
1246 fn active(&self) -> Option<K> {
1247 self.weave.active()
1248 }
1249}
1250
1251impl<W, K, N, T> ActivePathWeave<K, N, T> for CountedWeave<W, K, N, T>
1252where
1253 W: ActivePathWeave<K, N, T>,
1254 K: Hash + Copy + Eq + Ord,
1255 N: Node<K, T>,
1256{
1257 type Active = W::Active;
1258
1259 #[inline]
1260 fn active(&self) -> &Self::Active {
1261 self.weave.active()
1262 }
1263 #[inline]
1264 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
1265 self.weave.set_active_path(active);
1266 self.count.set_active_path = self.count.set_active_path.saturating_add(1);
1267 }
1268}
1269
1270impl<W, K, N, T> IndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1271where
1272 W: IndependentWeave<K, N, T>,
1273 K: Hash + Copy + Eq + Ord,
1274 N: Node<K, T>,
1275 T: IndependentContents,
1276{
1277 #[inline]
1278 fn move_to(&mut self, id: &K, new_parents: &[K]) -> bool {
1279 if self.weave.move_to(id, new_parents) {
1280 self.count.move_to = self.count.move_to.saturating_add(1);
1281 true
1282 } else {
1283 false
1284 }
1285 }
1286}
1287
1288impl<W, K, N, T> SemiIndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1289where
1290 W: SemiIndependentWeave<K, N, T>,
1291 K: Hash + Copy + Eq + Ord,
1292 N: Node<K, T>,
1293 T: IndependentContents,
1294{
1295 #[inline]
1296 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1297 self.weave.get_contents_mut(id, callback).inspect(|_| {
1298 self.count.get_contents_mut = self.count.get_contents_mut.saturating_add(1);
1299 })
1300 }
1301}
1302
1303impl<W, K, N, T> DiscreteWeave<K, N, T> for CountedWeave<W, K, N, T>
1304where
1305 W: DiscreteWeave<K, N, T>,
1306 K: Hash + Copy + Eq + Ord,
1307 N: Node<K, T>,
1308 T: DiscreteContents,
1309{
1310 #[inline]
1311 fn split(&mut self, id: &K, at: usize, new_id: K) -> bool {
1312 if self.weave.split(id, at, new_id) {
1313 self.count.split = self.count.split.saturating_add(1);
1314 true
1315 } else {
1316 false
1317 }
1318 }
1319 #[inline]
1320 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1321 match self.weave.merge_with_parent(id) {
1322 Some(new_id) => {
1323 self.count.merge_with_parent = self.count.merge_with_parent.saturating_add(1);
1324 Some(new_id)
1325 }
1326 None => None,
1327 }
1328 }
1329}
1330
1331#[derive(Default, Debug, Clone, PartialEq, Eq)]
1339#[must_use]
1340pub struct DeduplicatedWeave<W, K, N, T, S>
1341where
1342 W: Weave<K, N, T>,
1343 K: Hash + Copy + Eq + Ord,
1344 T: DeduplicatableContents,
1345 N: Node<K, T>,
1346 S: BuildHasher + Default + Clone,
1347 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1348 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1349 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1350{
1351 pub weave: W,
1355
1356 scratchpad: HashSet<K, S>,
1357 _phantom_n: PhantomData<N>,
1358 _phantom_t: PhantomData<T>,
1359}
1360
1361impl<W, K, N, T, S> DeduplicatedWeave<W, K, N, T, S>
1362where
1363 W: Weave<K, N, T>,
1364 K: Hash + Copy + Eq + Ord,
1365 T: DeduplicatableContents,
1366 N: Node<K, T>,
1367 S: BuildHasher + Default + Clone,
1368 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1369 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1370 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1371{
1372 pub fn new(weave: W) -> Self {
1374 Self {
1375 scratchpad: HashSet::with_capacity_and_hasher(weave.len(), S::default()),
1376 weave,
1377 _phantom_n: PhantomData,
1378 _phantom_t: PhantomData,
1379 }
1380 }
1381 #[inline]
1383 pub fn into_inner(self) -> W {
1384 self.weave
1385 }
1386 #[inline]
1388 pub const fn as_inner(&self) -> &W {
1389 &self.weave
1390 }
1391}
1392
1393fn has_duplicate_siblings<W, K, N, T, S, I, F, O>(
1394 weave: &W,
1395 ignored: &I,
1396 parents: &F,
1397 children: &O,
1398 contents: &T,
1399 scratchpad: &mut HashSet<K, S>,
1400) -> bool
1401where
1402 W: Weave<K, N, T>,
1403 K: Hash + Copy + Eq + Ord,
1404 T: DeduplicatableContents,
1405 N: Node<K, T>,
1406 S: BuildHasher + Default + Clone,
1407 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1408 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1409 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1410 for<'a> &'a I: IntoIterator<Item = &'a K>,
1411 for<'a> &'a F: IntoIterator<Item = &'a K>,
1412 for<'a> &'a O: IntoIterator<Item = &'a K>,
1413 F: ?Sized,
1414 O: ?Sized,
1415{
1416 if parents.into_iter().next().is_none() {
1417 scratchpad.extend(weave.roots().into_iter().copied());
1418 } else {
1419 for sibling in parents
1420 .into_iter()
1421 .filter_map(|id| weave.get_children(id))
1422 .flatten()
1423 .copied()
1424 {
1425 scratchpad.insert(sibling);
1426 }
1427 }
1428
1429 for parent in parents {
1430 scratchpad.remove(parent);
1431 }
1432
1433 for child in children {
1434 scratchpad.remove(child);
1435 }
1436
1437 for ignore in ignored {
1438 scratchpad.remove(ignore);
1439 }
1440
1441 scratchpad
1442 .drain()
1443 .filter_map(|id| weave.get_contents(&id))
1444 .any(|c| c.is_duplicate_of(contents))
1445}
1446
1447impl<W, K, N, T, S> Weave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1448where
1449 W: Weave<K, N, T>,
1450 K: Hash + Copy + Eq + Ord,
1451 T: DeduplicatableContents,
1452 N: Node<K, T>,
1453 S: BuildHasher + Default + Clone,
1454 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1455 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1456 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1457{
1458 type Nodes = W::Nodes;
1459 type Roots = W::Roots;
1460
1461 #[inline]
1462 fn len(&self) -> usize {
1463 self.weave.len()
1464 }
1465 #[inline]
1466 fn is_empty(&self) -> bool {
1467 self.weave.is_empty()
1468 }
1469 #[inline]
1470 fn nodes(&self) -> &Self::Nodes {
1471 self.weave.nodes()
1472 }
1473 #[inline]
1474 fn roots(&self) -> &Self::Roots {
1475 self.weave.roots()
1476 }
1477 #[inline]
1478 fn contains(&self, id: &K) -> bool {
1479 self.weave.contains(id)
1480 }
1481 #[inline]
1482 fn contains_active(&self, id: &K) -> bool {
1483 self.weave.contains_active(id)
1484 }
1485 #[inline]
1486 fn get(&self, id: &K) -> Option<&N> {
1487 self.weave.get(id)
1488 }
1489 #[inline]
1490 fn get_parents(&self, id: &K) -> Option<&N::From> {
1491 self.weave.get_parents(id)
1492 }
1493 #[inline]
1494 fn get_children(&self, id: &K) -> Option<&N::To> {
1495 self.weave.get_children(id)
1496 }
1497 #[inline]
1498 fn get_contents(&self, id: &K) -> Option<&T> {
1499 self.weave.get_contents(id)
1500 }
1501 #[inline]
1502 fn get_ordered_identifiers(&mut self, output: &mut Vec<K>) {
1503 self.weave.get_ordered_identifiers(output);
1504 }
1505 #[inline]
1506 fn get_ordered_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
1507 self.weave.get_ordered_identifiers_from(id, output);
1508 }
1509 #[inline]
1510 fn get_active_path(&mut self, output: &mut Vec<K>) {
1511 self.weave.get_active_path(output);
1512 }
1513 #[inline]
1514 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
1515 self.weave.get_path_from(id, output);
1516 }
1517 fn insert(&mut self, node: N) -> bool {
1525 if has_duplicate_siblings(
1526 &self.weave,
1527 &[node.id()],
1528 node.from(),
1529 node.to(),
1530 node.contents(),
1531 &mut self.scratchpad,
1532 ) {
1533 return false;
1534 }
1535
1536 self.weave.insert(node)
1537 }
1538 #[inline]
1539 fn set_active(&mut self, id: &K, value: bool) -> bool {
1540 self.weave.set_active(id, value)
1541 }
1542 #[inline]
1552 fn remove(&mut self, id: &K) -> Option<N> {
1553 self.weave.remove(id)
1554 }
1555 #[inline]
1567 fn remove_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
1568 self.weave.remove_tracked(id, on_removal)
1569 }
1570 #[inline]
1571 fn clear(&mut self) {
1572 self.weave.clear();
1573 }
1574}
1575
1576impl<W, K, N, T, M, S> MetadataWeave<K, N, T, M> for DeduplicatedWeave<W, K, N, T, S>
1577where
1578 W: MetadataWeave<K, N, T, M>,
1579 K: Hash + Copy + Eq + Ord,
1580 T: DeduplicatableContents,
1581 N: Node<K, T>,
1582 S: BuildHasher + Default + Clone,
1583 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1584 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1585 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1586{
1587 #[inline]
1588 fn metadata(&self) -> &M {
1589 self.weave.metadata()
1590 }
1591 #[inline]
1592 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
1593 self.weave.metadata_mut(callback)
1594 }
1595}
1596
1597impl<W, K, N, T, S> BookmarkableWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1598where
1599 W: BookmarkableWeave<K, N, T>,
1600 K: Hash + Copy + Eq + Ord,
1601 T: DeduplicatableContents,
1602 N: Node<K, T>,
1603 S: BuildHasher + Default + Clone,
1604 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1605 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1606 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1607{
1608 type Bookmarks = W::Bookmarks;
1609
1610 #[inline]
1611 fn bookmarks(&self) -> &Self::Bookmarks {
1612 self.weave.bookmarks()
1613 }
1614 #[inline]
1615 fn contains_bookmark(&self, id: &K) -> bool {
1616 self.weave.contains_bookmark(id)
1617 }
1618 #[inline]
1619 fn set_bookmarked(&mut self, id: &K, value: bool) -> bool {
1620 self.weave.set_bookmarked(id, value)
1621 }
1622}
1623
1624impl<W, K, N, T, S> SortableWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1625where
1626 W: SortableWeave<K, N, T>,
1627 K: Hash + Copy + Eq + Ord,
1628 T: DeduplicatableContents,
1629 N: Node<K, T>,
1630 S: BuildHasher + Default + Clone,
1631 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1632 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1633 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1634{
1635 #[inline]
1636 fn sort_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
1637 self.weave.sort_children_by(id, cmp)
1638 }
1639 #[inline]
1640 fn sort_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
1641 self.weave.sort_children_by_id(id, cmp)
1642 }
1643 #[inline]
1644 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1645 self.weave.sort_roots_by(cmp);
1646 }
1647 #[inline]
1648 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1649 self.weave.sort_roots_by_id(cmp);
1650 }
1651}
1652
1653impl<W, K, N, T, S> SortableBookmarkableWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1654where
1655 W: SortableBookmarkableWeave<K, N, T>,
1656 K: Hash + Copy + Eq + Ord,
1657 T: DeduplicatableContents,
1658 N: Node<K, T>,
1659 S: BuildHasher + Default + Clone,
1660 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1661 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1662 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1663{
1664 #[inline]
1665 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1666 self.weave.sort_bookmarks_by(cmp);
1667 }
1668 #[inline]
1669 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1670 self.weave.sort_bookmarks_by_id(cmp);
1671 }
1672}
1673
1674impl<W, K, N, T, S> ActiveSingularWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1675where
1676 W: ActiveSingularWeave<K, N, T>,
1677 K: Hash + Copy + Eq + Ord,
1678 T: DeduplicatableContents,
1679 N: Node<K, T>,
1680 S: BuildHasher + Default + Clone,
1681 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1682 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1683 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1684{
1685 #[inline]
1686 fn active(&self) -> Option<K> {
1687 self.weave.active()
1688 }
1689}
1690
1691impl<W, K, N, T, S> ActivePathWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1692where
1693 W: ActivePathWeave<K, N, T>,
1694 K: Hash + Copy + Eq + Ord,
1695 T: DeduplicatableContents,
1696 N: Node<K, T>,
1697 S: BuildHasher + Default + Clone,
1698 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1699 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1700 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1701{
1702 type Active = W::Active;
1703
1704 #[inline]
1705 fn active(&self) -> &Self::Active {
1706 self.weave.active()
1707 }
1708 #[inline]
1709 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
1710 self.weave.set_active_path(active);
1711 }
1712}
1713
1714impl<W, K, N, T, S> IndependentWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1715where
1716 W: IndependentWeave<K, N, T>,
1717 K: Hash + Copy + Eq + Ord,
1718 T: IndependentContents + DeduplicatableContents + Clone,
1719 N: Node<K, T>,
1720 S: BuildHasher + Default + Clone,
1721 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1722 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1723 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1724{
1725 fn move_to(&mut self, id: &K, new_parents: &[K]) -> bool {
1726 if let Some(node) = self.weave.get(id) {
1727 if has_duplicate_siblings(
1728 &self.weave,
1729 &[node.id()],
1730 new_parents,
1731 node.to(),
1732 node.contents(),
1733 &mut self.scratchpad,
1734 ) {
1735 return false;
1736 }
1737
1738 self.weave.move_to(id, new_parents)
1739 } else {
1740 false
1741 }
1742 }
1743}
1744
1745impl<W, K, N, T, S> SemiIndependentWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1746where
1747 W: SemiIndependentWeave<K, N, T>,
1748 K: Hash + Copy + Eq + Ord,
1749 T: IndependentContents + DeduplicatableContents + Clone,
1750 N: Node<K, T>,
1751 S: BuildHasher + Default + Clone,
1752 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1753 for<'a> &'a N::From: IntoIterator<Item = &'a K>,
1754 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1755{
1756 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1764 if let Some(node) = self.weave.get(id) {
1765 let mut contents = node.contents().clone();
1766 let output = callback(&mut contents);
1767
1768 if has_duplicate_siblings(
1769 &self.weave,
1770 &[node.id()],
1771 node.from(),
1772 node.to(),
1773 &contents,
1774 &mut self.scratchpad,
1775 ) {
1776 None
1777 } else if self.weave.get_contents_mut(id, |c| *c = contents).is_some() {
1778 Some(output)
1779 } else {
1780 None
1781 }
1782 } else {
1783 None
1784 }
1785 }
1786}
1787
1788impl<W, K, N, T, S> DiscreteWeave<K, N, T> for DeduplicatedWeave<W, K, N, T, S>
1789where
1790 W: DiscreteWeave<K, N, T>,
1791 K: Hash + Copy + Eq + Ord,
1792 T: DiscreteContents + DeduplicatableContents + Clone,
1793 N: Node<K, T>,
1794 S: BuildHasher + Default + Clone,
1795 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
1796 for<'a> &'a N::From: IntoIterator<Item = &'a K, IntoIter: ExactSizeIterator>,
1797 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
1798{
1799 fn split(&mut self, id: &K, at: usize, new_id: K) -> bool {
1800 if let Some(node) = self.weave.get(id)
1801 && let DiscreteContentResult::Two(left, _right) = node.contents().clone().split(at)
1802 && has_duplicate_siblings(
1803 &self.weave,
1804 &[node.id()],
1805 node.from(),
1806 &[],
1807 &left,
1808 &mut self.scratchpad,
1809 )
1810 {
1811 return false;
1812 }
1813
1814 self.weave.split(id, at, new_id)
1815 }
1816 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1817 if let Some(node) = self.weave.get(id) {
1818 if node.from().into_iter().len() != 1 {
1819 return None;
1820 }
1821
1822 if let Some(parent_id) = node.from().into_iter().next()
1823 && let Some(parent) = self.weave.get(parent_id)
1824 && let DiscreteContentResult::One(merged) =
1825 parent.contents().clone().merge(node.contents().clone())
1826 && has_duplicate_siblings(
1827 &self.weave,
1828 &[node.id(), *parent_id],
1829 parent.from(),
1830 node.to(),
1831 &merged,
1832 &mut self.scratchpad,
1833 )
1834 {
1835 return None;
1836 }
1837 }
1838
1839 self.weave.merge_with_parent(id)
1840 }
1841}