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;
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 DeduplicatableWeave, 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 AddNode(N),
140 SetNodeActiveStatus { id: K, value: bool },
142 SetNodeBookmarkedStatus { id: K, value: bool },
144 RemoveNode(K),
146 RemoveAllNodes,
148 SetMetadata(M),
150 SetNodeChildOrdering { parent: Option<K>, children: Vec<K> },
152 SetBookmarkOrdering(Vec<K>),
154 SetActivePath(Vec<K>),
156 MoveNode { id: K, new_parents: Vec<K> },
158 SetNodeContent { id: K, contents: T },
160 SplitNode { id: K, at: usize, new_id: K },
162 MergeNodeWithParent(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 add_node: usize,
278 pub set_node_active_status: usize,
280 pub set_node_bookmarked_status: usize,
282 pub remove_node: usize,
284 pub remove_all_nodes: usize,
286 pub metadata_mut: usize,
288 pub sort_node_children: usize,
290 pub sort_roots: usize,
292 pub sort_bookmarks: usize,
294 pub set_active_path: usize,
296 pub move_node: usize,
298 pub get_contents_mut: usize,
300 pub split_node: 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.add_node
323 .saturating_add(self.set_node_active_status)
324 .saturating_add(self.set_node_bookmarked_status)
325 .saturating_add(self.remove_node)
326 .saturating_add(self.remove_all_nodes)
327 .saturating_add(self.metadata_mut)
328 .saturating_add(self.sort_node_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_node)
333 .saturating_add(self.get_contents_mut)
334 .saturating_add(self.split_node)
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::AddNode(_node) => self.add_node = self.add_node.saturating_add(1),
346 WeaveAction::SetNodeActiveStatus { .. } => {
347 self.set_node_active_status = self.set_node_active_status.saturating_add(1);
348 }
349 WeaveAction::SetNodeBookmarkedStatus { .. } => {
350 self.set_node_bookmarked_status = self.set_node_bookmarked_status.saturating_add(1);
351 }
352 WeaveAction::RemoveNode(_id) => self.remove_node = self.remove_node.saturating_add(1),
353 WeaveAction::RemoveAllNodes => {
354 self.remove_all_nodes = self.remove_all_nodes.saturating_add(1);
355 }
356 WeaveAction::SetMetadata(_metadata) => {
357 self.metadata_mut = self.metadata_mut.saturating_add(1);
358 }
359 WeaveAction::SetNodeChildOrdering { parent, .. } => match parent {
360 Some(_id) => self.sort_node_children = self.sort_node_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::MoveNode { .. } => self.move_node = self.move_node.saturating_add(1),
370 WeaveAction::SetNodeContent { .. } => {
371 self.get_contents_mut = self.get_contents_mut.saturating_add(1);
372 }
373 WeaveAction::SplitNode { .. } => self.split_node = self.split_node.saturating_add(1),
374 WeaveAction::MergeNodeWithParent(_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::AddNode(_node) => self.add_node = self.add_node.saturating_sub(1),
387 WeaveAction::SetNodeActiveStatus { .. } => {
388 self.set_node_active_status = self.set_node_active_status.saturating_sub(1);
389 }
390 WeaveAction::SetNodeBookmarkedStatus { .. } => {
391 self.set_node_bookmarked_status = self.set_node_bookmarked_status.saturating_sub(1);
392 }
393 WeaveAction::RemoveNode(_id) => self.remove_node = self.remove_node.saturating_sub(1),
394 WeaveAction::RemoveAllNodes => {
395 self.remove_all_nodes = self.remove_all_nodes.saturating_sub(1);
396 }
397 WeaveAction::SetMetadata(_metadata) => {
398 self.metadata_mut = self.metadata_mut.saturating_sub(1);
399 }
400 WeaveAction::SetNodeChildOrdering { parent, .. } => match parent {
401 Some(_id) => self.sort_node_children = self.sort_node_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::MoveNode { .. } => self.move_node = self.move_node.saturating_sub(1),
411 WeaveAction::SetNodeContent { .. } => {
412 self.get_contents_mut = self.get_contents_mut.saturating_sub(1);
413 }
414 WeaveAction::SplitNode { .. } => self.split_node = self.split_node.saturating_sub(1),
415 WeaveAction::MergeNodeWithParent(_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>
535 for dependent::DependentWeave<K, T, M, S>
536where
537 K: Hash + Copy + Eq + Ord,
538 T: IndependentContents + DiscreteContents,
539 S: BuildHasher + Default + Clone,
540{
541 #[allow(clippy::panic, reason = "Necessary due to API shape")]
542 fn apply(&mut self, action: WeaveAction<K, dependent::DependentNode<K, T, S>, T, M>) {
543 match action {
544 WeaveAction::AddNode(node) => {
545 assert!(self.add_node(node), "Failed to apply Weave action");
546 }
547 WeaveAction::SetNodeActiveStatus { id, value } => {
548 assert!(
549 self.set_node_active_status(&id, value),
550 "Failed to apply Weave action"
551 );
552 }
553 WeaveAction::SetNodeBookmarkedStatus { id, value } => {
554 assert!(
555 self.set_node_bookmarked_status(&id, value),
556 "Failed to apply Weave action"
557 );
558 }
559 WeaveAction::RemoveNode(id) => assert!(
560 self.remove_node(&id).is_some(),
561 "Failed to apply Weave action"
562 ),
563 WeaveAction::RemoveAllNodes => self.remove_all_nodes(),
564 WeaveAction::SetMetadata(metadata) => {
565 self.metadata_mut(|m| *m = metadata);
566 }
567 WeaveAction::SetNodeChildOrdering { parent, children } => {
568 let mut id_mapping =
569 HashMap::with_capacity_and_hasher(children.len(), S::default());
570 id_mapping.extend(
571 children
572 .into_iter()
573 .enumerate()
574 .map(|(index, id)| (id, index)),
575 );
576
577 match parent {
578 Some(id) => {
579 assert!(
580 self.sort_node_children_by_id(&id, |a, b| {
581 id_mapping[a].cmp(&id_mapping[b])
582 }),
583 "Failed to apply Weave action"
584 );
585 }
586 None => {
587 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
588 }
589 }
590 }
591 WeaveAction::SetBookmarkOrdering(ids) => {
592 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
593 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
594
595 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
596 }
597 WeaveAction::SetActivePath(_) => {
598 panic!("Weave does not implement set_active_path()");
599 }
600 WeaveAction::MoveNode { .. } => {
601 panic!("Weave does not implement move_node()");
602 }
603 WeaveAction::SetNodeContent { id, contents } => {
604 assert!(
605 self.get_contents_mut(&id, |c| *c = contents).is_some(),
606 "Failed to apply Weave action"
607 );
608 }
609 WeaveAction::SplitNode { id, at, new_id } => assert!(
610 self.split_node(&id, at, new_id),
611 "Failed to apply Weave action"
612 ),
613 WeaveAction::MergeNodeWithParent(id) => assert!(
614 self.merge_with_parent(&id).is_some(),
615 "Failed to apply Weave action"
616 ),
617 }
618 }
619}
620
621impl<K, T, M, S> ActionableWeave<K, independent::IndependentNode<K, T, S>, T, M, S>
623 for independent::IndependentWeave<K, T, M, S>
624where
625 K: Hash + Copy + Eq + Ord,
626 T: IndependentContents + DiscreteContents,
627 S: BuildHasher + Default + Clone,
628{
629 fn apply(&mut self, action: WeaveAction<K, independent::IndependentNode<K, T, S>, T, M>) {
630 match action {
631 WeaveAction::AddNode(node) => {
632 assert!(self.add_node(node), "Failed to apply Weave action");
633 }
634 WeaveAction::SetNodeActiveStatus { id, value } => {
635 assert!(
636 self.set_node_active_status(&id, value),
637 "Failed to apply Weave action"
638 );
639 }
640 WeaveAction::SetNodeBookmarkedStatus { id, value } => {
641 assert!(
642 self.set_node_bookmarked_status(&id, value),
643 "Failed to apply Weave action"
644 );
645 }
646 WeaveAction::RemoveNode(id) => assert!(
647 self.remove_node(&id).is_some(),
648 "Failed to apply Weave action"
649 ),
650 WeaveAction::RemoveAllNodes => self.remove_all_nodes(),
651 WeaveAction::SetMetadata(metadata) => {
652 self.metadata_mut(|m| *m = metadata);
653 }
654 WeaveAction::SetNodeChildOrdering { parent, children } => {
655 let mut id_mapping =
656 HashMap::with_capacity_and_hasher(children.len(), S::default());
657 id_mapping.extend(
658 children
659 .into_iter()
660 .enumerate()
661 .map(|(index, id)| (id, index)),
662 );
663
664 match parent {
665 Some(id) => {
666 assert!(
667 self.sort_node_children_by_id(&id, |a, b| {
668 id_mapping[a].cmp(&id_mapping[b])
669 }),
670 "Failed to apply Weave action"
671 );
672 }
673 None => {
674 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
675 }
676 }
677 }
678 WeaveAction::SetBookmarkOrdering(ids) => {
679 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
680 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
681
682 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
683 }
684 WeaveAction::SetActivePath(active) => {
685 self.set_active_path(active.into_iter());
686 }
687 WeaveAction::MoveNode { id, new_parents } => assert!(
688 self.move_node(&id, &new_parents),
689 "Failed to apply Weave action"
690 ),
691 WeaveAction::SetNodeContent { id, contents } => {
692 assert!(
693 self.get_contents_mut(&id, |c| *c = contents).is_some(),
694 "Failed to apply Weave action"
695 );
696 }
697 WeaveAction::SplitNode { id, at, new_id } => assert!(
698 self.split_node(&id, at, new_id),
699 "Failed to apply Weave action"
700 ),
701 WeaveAction::MergeNodeWithParent(id) => assert!(
702 self.merge_with_parent(&id).is_some(),
703 "Failed to apply Weave action"
704 ),
705 }
706 }
707}
708
709impl<W, K, N, T, M> Weave<K, N, T> for LoggedWeave<W, K, N, T, M>
710where
711 W: Weave<K, N, T>,
712 K: Hash + Copy + Eq + Ord,
713 N: Node<K, T> + Clone,
714{
715 type Nodes = W::Nodes;
716 type Roots = W::Roots;
717
718 #[inline]
719 fn len(&self) -> usize {
720 self.weave.len()
721 }
722 #[inline]
723 fn is_empty(&self) -> bool {
724 self.weave.is_empty()
725 }
726 #[inline]
727 fn nodes(&self) -> &Self::Nodes {
728 self.weave.nodes()
729 }
730 #[inline]
731 fn roots(&self) -> &Self::Roots {
732 self.weave.roots()
733 }
734 #[inline]
735 fn contains(&self, id: &K) -> bool {
736 self.weave.contains(id)
737 }
738 #[inline]
739 fn contains_active(&self, id: &K) -> bool {
740 self.weave.contains_active(id)
741 }
742 #[inline]
743 fn get_node(&self, id: &K) -> Option<&N> {
744 self.weave.get_node(id)
745 }
746 #[inline]
747 fn get_ordered_node_identifiers(&mut self, output: &mut Vec<K>) {
748 self.weave.get_ordered_node_identifiers(output);
749 }
750 #[inline]
751 fn get_ordered_node_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
752 self.weave.get_ordered_node_identifiers_from(id, output);
753 }
754 #[inline]
755 fn get_active_path(&mut self, output: &mut Vec<K>) {
756 self.weave.get_active_path(output);
757 }
758 #[inline]
759 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
760 self.weave.get_path_from(id, output);
761 }
762 fn add_node(&mut self, node: N) -> bool {
763 if self.weave.add_node(node.clone()) {
764 self.actions.push_back(WeaveAction::AddNode(node));
765 true
766 } else {
767 false
768 }
769 }
770 fn set_node_active_status(&mut self, id: &K, value: bool) -> bool {
771 if self.weave.set_node_active_status(id, value) {
772 self.actions
773 .push_back(WeaveAction::SetNodeActiveStatus { id: *id, value });
774 true
775 } else {
776 false
777 }
778 }
779 fn remove_node(&mut self, id: &K) -> Option<N> {
780 if let Some(removed) = self.weave.remove_node(id) {
781 self.actions.push_back(WeaveAction::RemoveNode(*id));
782 Some(removed)
783 } else {
784 None
785 }
786 }
787 fn remove_node_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
788 if self.weave.remove_node_tracked(id, on_removal) {
789 self.actions.push_back(WeaveAction::RemoveNode(*id));
790 true
791 } else {
792 false
793 }
794 }
795 fn remove_all_nodes(&mut self) {
796 self.weave.remove_all_nodes();
797 self.actions.push_back(WeaveAction::RemoveAllNodes);
798 }
799}
800
801impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for LoggedWeave<W, K, N, T, M>
802where
803 W: MetadataWeave<K, N, T, M>,
804 K: Hash + Copy + Eq + Ord,
805 N: Node<K, T> + Clone,
806 M: Clone,
807{
808 #[inline]
809 fn metadata(&self) -> &M {
810 self.weave.metadata()
811 }
812 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
813 self.weave.metadata_mut(|metadata| {
814 let output = callback(metadata);
815
816 self.actions
817 .push_back(WeaveAction::SetMetadata(metadata.clone()));
818
819 output
820 })
821 }
822}
823
824impl<W, K, N, T, M> BookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
825where
826 W: BookmarkableWeave<K, N, T>,
827 K: Hash + Copy + Eq + Ord,
828 N: Node<K, T> + Clone,
829{
830 type Bookmarks = W::Bookmarks;
831
832 #[inline]
833 fn bookmarks(&self) -> &Self::Bookmarks {
834 self.weave.bookmarks()
835 }
836 #[inline]
837 fn contains_bookmark(&self, id: &K) -> bool {
838 self.weave.contains_bookmark(id)
839 }
840 fn set_node_bookmarked_status(&mut self, id: &K, value: bool) -> bool {
841 if self.weave.set_node_bookmarked_status(id, value) {
842 self.actions
843 .push_back(WeaveAction::SetNodeBookmarkedStatus { id: *id, value });
844 true
845 } else {
846 false
847 }
848 }
849}
850
851impl<W, K, N, T, M> SortableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
852where
853 W: SortableWeave<K, N, T>,
854 K: Hash + Copy + Eq + Ord,
855 N: Node<K, T> + Clone,
856 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
857 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
858{
859 #[inline]
860 fn get_ordered_node_identifiers_mirrored(&mut self, output: &mut Vec<K>) {
861 self.weave.get_ordered_node_identifiers_mirrored(output);
862 }
863 #[inline]
864 fn get_ordered_node_identifiers_mirrored_from(&mut self, id: &K, output: &mut Vec<K>) {
865 self.weave
866 .get_ordered_node_identifiers_mirrored_from(id, output);
867 }
868 fn sort_node_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
869 if self.weave.sort_node_children_by(id, cmp) {
870 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
871 parent: Some(*id),
872 children: self
873 .weave
874 .get_node(id)
875 .unwrap()
876 .to()
877 .into_iter()
878 .copied()
879 .collect(),
880 });
881 true
882 } else {
883 false
884 }
885 }
886 fn sort_node_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
887 if self.weave.sort_node_children_by_id(id, cmp) {
888 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
889 parent: Some(*id),
890 children: self
891 .weave
892 .get_node(id)
893 .unwrap()
894 .to()
895 .into_iter()
896 .copied()
897 .collect(),
898 });
899 true
900 } else {
901 false
902 }
903 }
904 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
905 self.weave.sort_roots_by(cmp);
906 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
907 parent: None,
908 children: self.weave.roots().into_iter().copied().collect(),
909 });
910 }
911 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
912 self.weave.sort_roots_by_id(cmp);
913 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
914 parent: None,
915 children: self.weave.roots().into_iter().copied().collect(),
916 });
917 }
918}
919
920impl<W, K, N, T, M> SortableBookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
921where
922 W: SortableBookmarkableWeave<K, N, T>,
923 K: Hash + Copy + Eq + Ord,
924 N: Node<K, T> + Clone,
925 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
926 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
927 for<'a> &'a W::Bookmarks: IntoIterator<Item = &'a K>,
928{
929 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
930 self.weave.sort_bookmarks_by(cmp);
931 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
932 self.weave.bookmarks().into_iter().copied().collect(),
933 ));
934 }
935 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
936 self.weave.sort_bookmarks_by_id(cmp);
937 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
938 self.weave.bookmarks().into_iter().copied().collect(),
939 ));
940 }
941}
942
943impl<W, K, N, T, M> ActiveSingularWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
944where
945 W: ActiveSingularWeave<K, N, T>,
946 K: Hash + Copy + Eq + Ord,
947 N: Node<K, T> + Clone,
948{
949 #[inline]
950 fn active(&self) -> Option<K> {
951 self.weave.active()
952 }
953}
954
955impl<W, K, N, T, M> ActivePathWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
956where
957 W: ActivePathWeave<K, N, T>,
958 K: Hash + Copy + Eq + Ord,
959 N: Node<K, T> + Clone,
960{
961 type Active = W::Active;
962
963 #[inline]
964 fn active(&self) -> &Self::Active {
965 self.weave.active()
966 }
967 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
968 let active: Vec<K> = active.collect();
969
970 self.weave.set_active_path(active.iter().copied());
971 self.actions.push_back(WeaveAction::SetActivePath(active));
972 }
973}
974
975impl<W, K, N, T, M> IndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
976where
977 W: IndependentWeave<K, N, T>,
978 K: Hash + Copy + Eq + Ord,
979 N: Node<K, T> + Clone,
980 T: IndependentContents + Clone,
981{
982 fn move_node(&mut self, id: &K, new_parents: &[K]) -> bool {
983 if self.weave.move_node(id, new_parents) {
984 self.actions.push_back(WeaveAction::MoveNode {
985 id: *id,
986 new_parents: new_parents.to_vec(),
987 });
988 true
989 } else {
990 false
991 }
992 }
993}
994
995impl<W, K, N, T, M> SemiIndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
996where
997 W: SemiIndependentWeave<K, N, T>,
998 K: Hash + Copy + Eq + Ord,
999 N: Node<K, T> + Clone,
1000 T: IndependentContents + Clone,
1001{
1002 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1003 self.weave.get_contents_mut(id, |contents| {
1004 let output = callback(contents);
1005
1006 self.actions.push_back(WeaveAction::SetNodeContent {
1007 id: *id,
1008 contents: contents.clone(),
1009 });
1010
1011 output
1012 })
1013 }
1014}
1015
1016impl<W, K, N, T, M> DiscreteWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
1017where
1018 W: DiscreteWeave<K, N, T>,
1019 K: Hash + Copy + Eq + Ord,
1020 N: Node<K, T> + Clone,
1021 T: DiscreteContents,
1022{
1023 fn split_node(&mut self, id: &K, at: usize, new_id: K) -> bool {
1024 if self.weave.split_node(id, at, new_id) {
1025 self.actions.push_back(WeaveAction::SplitNode {
1026 id: *id,
1027 at,
1028 new_id,
1029 });
1030 true
1031 } else {
1032 false
1033 }
1034 }
1035 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1036 match self.weave.merge_with_parent(id) {
1037 Some(new_id) => {
1038 self.actions
1039 .push_back(WeaveAction::MergeNodeWithParent(*id));
1040 Some(new_id)
1041 }
1042 None => None,
1043 }
1044 }
1045}
1046
1047impl<W, K, N, T, M> DeduplicatableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
1048where
1049 W: DeduplicatableWeave<K, N, T>,
1050 K: Hash + Copy + Eq + Ord,
1051 N: Node<K, T> + Clone,
1052 T: DeduplicatableContents,
1053{
1054 #[inline]
1055 fn find_duplicates(&self, id: &K) -> impl Iterator<Item = K> {
1056 self.weave.find_duplicates(id)
1057 }
1058}
1059
1060impl<W, K, N, T> Weave<K, N, T> for CountedWeave<W, K, N, T>
1061where
1062 W: Weave<K, N, T>,
1063 K: Hash + Copy + Eq + Ord,
1064 N: Node<K, T>,
1065{
1066 type Nodes = W::Nodes;
1067 type Roots = W::Roots;
1068
1069 #[inline]
1070 fn len(&self) -> usize {
1071 self.weave.len()
1072 }
1073 #[inline]
1074 fn is_empty(&self) -> bool {
1075 self.weave.is_empty()
1076 }
1077 #[inline]
1078 fn nodes(&self) -> &Self::Nodes {
1079 self.weave.nodes()
1080 }
1081 #[inline]
1082 fn roots(&self) -> &Self::Roots {
1083 self.weave.roots()
1084 }
1085 #[inline]
1086 fn contains(&self, id: &K) -> bool {
1087 self.weave.contains(id)
1088 }
1089 #[inline]
1090 fn contains_active(&self, id: &K) -> bool {
1091 self.weave.contains_active(id)
1092 }
1093 #[inline]
1094 fn get_node(&self, id: &K) -> Option<&N> {
1095 self.weave.get_node(id)
1096 }
1097 #[inline]
1098 fn get_ordered_node_identifiers(&mut self, output: &mut Vec<K>) {
1099 self.weave.get_ordered_node_identifiers(output);
1100 }
1101 #[inline]
1102 fn get_ordered_node_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
1103 self.weave.get_ordered_node_identifiers_from(id, output);
1104 }
1105 #[inline]
1106 fn get_active_path(&mut self, output: &mut Vec<K>) {
1107 self.weave.get_active_path(output);
1108 }
1109 #[inline]
1110 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
1111 self.weave.get_path_from(id, output);
1112 }
1113 #[inline]
1114 fn add_node(&mut self, node: N) -> bool {
1115 if self.weave.add_node(node) {
1116 self.count.add_node = self.count.add_node.saturating_add(1);
1117 true
1118 } else {
1119 false
1120 }
1121 }
1122 #[inline]
1123 fn set_node_active_status(&mut self, id: &K, value: bool) -> bool {
1124 if self.weave.set_node_active_status(id, value) {
1125 self.count.set_node_active_status = self.count.set_node_active_status.saturating_add(1);
1126 true
1127 } else {
1128 false
1129 }
1130 }
1131 #[inline]
1132 fn remove_node(&mut self, id: &K) -> Option<N> {
1133 if let Some(removed) = self.weave.remove_node(id) {
1134 self.count.remove_node = self.count.remove_node.saturating_add(1);
1135 Some(removed)
1136 } else {
1137 None
1138 }
1139 }
1140 #[inline]
1141 fn remove_node_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
1142 if self.weave.remove_node_tracked(id, on_removal) {
1143 self.count.remove_node = self.count.remove_node.saturating_add(1);
1144 true
1145 } else {
1146 false
1147 }
1148 }
1149 #[inline]
1150 fn remove_all_nodes(&mut self) {
1151 self.weave.remove_all_nodes();
1152 self.count.remove_all_nodes = self.count.remove_all_nodes.saturating_add(1);
1153 }
1154}
1155
1156impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for CountedWeave<W, K, N, T>
1157where
1158 W: MetadataWeave<K, N, T, M>,
1159 K: Hash + Copy + Eq + Ord,
1160 N: Node<K, T>,
1161{
1162 #[inline]
1163 fn metadata(&self) -> &M {
1164 self.weave.metadata()
1165 }
1166 #[inline]
1167 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
1168 self.weave.metadata_mut(|metadata| {
1169 let output = callback(metadata);
1170 self.count.metadata_mut = self.count.metadata_mut.saturating_add(1);
1171 output
1172 })
1173 }
1174}
1175
1176impl<W, K, N, T> BookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1177where
1178 W: BookmarkableWeave<K, N, T>,
1179 K: Hash + Copy + Eq + Ord,
1180 N: Node<K, T>,
1181{
1182 type Bookmarks = W::Bookmarks;
1183
1184 #[inline]
1185 fn bookmarks(&self) -> &Self::Bookmarks {
1186 self.weave.bookmarks()
1187 }
1188 #[inline]
1189 fn contains_bookmark(&self, id: &K) -> bool {
1190 self.weave.contains_bookmark(id)
1191 }
1192 #[inline]
1193 fn set_node_bookmarked_status(&mut self, id: &K, value: bool) -> bool {
1194 if self.weave.set_node_bookmarked_status(id, value) {
1195 self.count.set_node_bookmarked_status =
1196 self.count.set_node_bookmarked_status.saturating_add(1);
1197 true
1198 } else {
1199 false
1200 }
1201 }
1202}
1203
1204impl<W, K, N, T> SortableWeave<K, N, T> for CountedWeave<W, K, N, T>
1205where
1206 W: SortableWeave<K, N, T>,
1207 K: Hash + Copy + Eq + Ord,
1208 N: Node<K, T>,
1209{
1210 #[inline]
1211 fn get_ordered_node_identifiers_mirrored(&mut self, output: &mut Vec<K>) {
1212 self.weave.get_ordered_node_identifiers_mirrored(output);
1213 }
1214 #[inline]
1215 fn get_ordered_node_identifiers_mirrored_from(&mut self, id: &K, output: &mut Vec<K>) {
1216 self.weave
1217 .get_ordered_node_identifiers_mirrored_from(id, output);
1218 }
1219 #[inline]
1220 fn sort_node_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
1221 if self.weave.sort_node_children_by(id, cmp) {
1222 self.count.sort_node_children = self.count.sort_node_children.saturating_add(1);
1223 true
1224 } else {
1225 false
1226 }
1227 }
1228 #[inline]
1229 fn sort_node_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
1230 if self.weave.sort_node_children_by_id(id, cmp) {
1231 self.count.sort_node_children = self.count.sort_node_children.saturating_add(1);
1232 true
1233 } else {
1234 false
1235 }
1236 }
1237 #[inline]
1238 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1239 self.weave.sort_roots_by(cmp);
1240 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1241 }
1242 #[inline]
1243 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1244 self.weave.sort_roots_by_id(cmp);
1245 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1246 }
1247}
1248
1249impl<W, K, N, T> SortableBookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1250where
1251 W: SortableBookmarkableWeave<K, N, T>,
1252 K: Hash + Copy + Eq + Ord,
1253 N: Node<K, T>,
1254{
1255 #[inline]
1256 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1257 self.weave.sort_bookmarks_by(cmp);
1258 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1259 }
1260 #[inline]
1261 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1262 self.weave.sort_bookmarks_by_id(cmp);
1263 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1264 }
1265}
1266
1267impl<W, K, N, T> ActiveSingularWeave<K, N, T> for CountedWeave<W, K, N, T>
1268where
1269 W: ActiveSingularWeave<K, N, T>,
1270 K: Hash + Copy + Eq + Ord,
1271 N: Node<K, T>,
1272{
1273 #[inline]
1274 fn active(&self) -> Option<K> {
1275 self.weave.active()
1276 }
1277}
1278
1279impl<W, K, N, T> ActivePathWeave<K, N, T> for CountedWeave<W, K, N, T>
1280where
1281 W: ActivePathWeave<K, N, T>,
1282 K: Hash + Copy + Eq + Ord,
1283 N: Node<K, T>,
1284{
1285 type Active = W::Active;
1286
1287 #[inline]
1288 fn active(&self) -> &Self::Active {
1289 self.weave.active()
1290 }
1291 #[inline]
1292 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
1293 self.weave.set_active_path(active);
1294 self.count.set_active_path = self.count.set_active_path.saturating_add(1);
1295 }
1296}
1297
1298impl<W, K, N, T> IndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1299where
1300 W: IndependentWeave<K, N, T>,
1301 K: Hash + Copy + Eq + Ord,
1302 N: Node<K, T>,
1303 T: IndependentContents,
1304{
1305 #[inline]
1306 fn move_node(&mut self, id: &K, new_parents: &[K]) -> bool {
1307 if self.weave.move_node(id, new_parents) {
1308 self.count.move_node = self.count.move_node.saturating_add(1);
1309 true
1310 } else {
1311 false
1312 }
1313 }
1314}
1315
1316impl<W, K, N, T> SemiIndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1317where
1318 W: SemiIndependentWeave<K, N, T>,
1319 K: Hash + Copy + Eq + Ord,
1320 N: Node<K, T>,
1321 T: IndependentContents,
1322{
1323 #[inline]
1324 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1325 self.weave.get_contents_mut(id, |contents| {
1326 let output = callback(contents);
1327 self.count.get_contents_mut = self.count.get_contents_mut.saturating_add(1);
1328 output
1329 })
1330 }
1331}
1332
1333impl<W, K, N, T> DiscreteWeave<K, N, T> for CountedWeave<W, K, N, T>
1334where
1335 W: DiscreteWeave<K, N, T>,
1336 K: Hash + Copy + Eq + Ord,
1337 N: Node<K, T>,
1338 T: DiscreteContents,
1339{
1340 #[inline]
1341 fn split_node(&mut self, id: &K, at: usize, new_id: K) -> bool {
1342 if self.weave.split_node(id, at, new_id) {
1343 self.count.split_node = self.count.split_node.saturating_add(1);
1344 true
1345 } else {
1346 false
1347 }
1348 }
1349 #[inline]
1350 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1351 match self.weave.merge_with_parent(id) {
1352 Some(new_id) => {
1353 self.count.merge_with_parent = self.count.merge_with_parent.saturating_add(1);
1354 Some(new_id)
1355 }
1356 None => None,
1357 }
1358 }
1359}
1360
1361impl<W, K, N, T> DeduplicatableWeave<K, N, T> for CountedWeave<W, K, N, T>
1362where
1363 W: DeduplicatableWeave<K, N, T>,
1364 K: Hash + Copy + Eq + Ord,
1365 N: Node<K, T>,
1366 T: DeduplicatableContents,
1367{
1368 #[inline]
1369 fn find_duplicates(&self, id: &K) -> impl Iterator<Item = K> {
1370 self.weave.find_duplicates(id)
1371 }
1372}