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, DiscreteContents, DiscreteWeave,
22 IndependentContents, IndependentWeave, MetadataWeave, Node, SemiIndependentWeave,
23 SortableBookmarkableWeave, SortableWeave, Weave, dependent, independent,
24};
25
26#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
30#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
31#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
32#[must_use]
33pub struct LoggedWeave<W, K, N, T, M>
34where
35 W: Weave<K, N, T>,
36 K: Hash + Copy + Eq + Ord,
37 N: Node<K, T>,
38{
39 pub weave: W,
43
44 pub actions: VecDeque<WeaveAction<K, N, T, M>>,
46}
47
48impl<W, K, N, T, M> AsRef<W> for LoggedWeave<W, K, N, T, M>
49where
50 W: Weave<K, N, T>,
51 K: Hash + Copy + Eq + Ord,
52 N: Node<K, T>,
53{
54 #[inline]
55 fn as_ref(&self) -> &W {
56 &self.weave
57 }
58}
59
60impl<W, K, N, T, M> From<W> for LoggedWeave<W, K, N, T, M>
61where
62 W: Weave<K, N, T>,
63 K: Hash + Copy + Eq + Ord,
64 N: Node<K, T>,
65{
66 #[inline]
67 fn from(value: W) -> Self {
68 Self {
69 weave: value,
70 actions: VecDeque::new(),
71 }
72 }
73}
74
75impl<W, K, N, T, M> LoggedWeave<W, K, N, T, M>
76where
77 W: Weave<K, N, T>,
78 K: Hash + Copy + Eq + Ord,
79 N: Node<K, T>,
80{
81 #[inline]
83 pub fn with_capacity(weave: W, capacity: usize) -> Self {
84 Self {
85 actions: VecDeque::with_capacity(capacity),
86 weave,
87 }
88 }
89 #[inline]
91 pub fn into_weave(self) -> W {
92 self.weave
93 }
94 #[inline]
96 pub const fn as_weave(&self) -> &W {
97 &self.weave
98 }
99 #[inline]
101 pub const fn as_actions(&self) -> &VecDeque<WeaveAction<K, N, T, M>> {
102 &self.actions
103 }
104 #[inline]
106 pub fn clear_actions(&mut self) {
107 self.actions.clear();
108 }
109 pub fn count_actions(&self) -> WeaveActionCount {
111 let mut count = WeaveActionCount::new();
112
113 for action in &self.actions {
114 count.increment(action);
115 }
116
117 count
118 }
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
127#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
128#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
129#[allow(clippy::doc_paragraphs_missing_punctuation, reason = "False positive")]
130#[non_exhaustive]
131#[must_use]
132pub enum WeaveAction<K, N, T, M>
133where
134 K: Hash + Copy + Eq + Ord,
135 N: Node<K, T>,
136{
137 AddNode(N),
139 SetNodeActiveStatus { id: K, value: bool },
141 SetNodeBookmarkedStatus { id: K, value: bool },
143 RemoveNode(K),
145 RemoveAllNodes,
147 SetMetadata(M),
149 SetNodeChildOrdering { parent: Option<K>, children: Vec<K> },
151 SetBookmarkOrdering(Vec<K>),
153 SetActivePath(Vec<K>),
155 MoveNode { id: K, new_parents: Vec<K> },
157 SetNodeContent { id: K, contents: T },
159 SplitNode { id: K, at: usize, new_id: K },
161 MergeNodeWithParent(K),
163}
164
165#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
169#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
170#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
171#[must_use]
172pub struct CountedWeave<W, K, N, T>
173where
174 W: Weave<K, N, T>,
175 K: Hash + Copy + Eq + Ord,
176 N: Node<K, T>,
177{
178 pub weave: W,
182
183 pub count: WeaveActionCount,
185
186 _phantom_k: PhantomData<K>,
187 _phantom_n: PhantomData<N>,
188 _phantom_t: PhantomData<T>,
189}
190
191impl<W, K, N, T> AsRef<W> for CountedWeave<W, K, N, T>
192where
193 W: Weave<K, N, T>,
194 K: Hash + Copy + Eq + Ord,
195 N: Node<K, T>,
196{
197 #[inline]
198 fn as_ref(&self) -> &W {
199 &self.weave
200 }
201}
202
203impl<W, K, N, T> From<W> for CountedWeave<W, K, N, T>
204where
205 W: Weave<K, N, T>,
206 K: Hash + Copy + Eq + Ord,
207 N: Node<K, T>,
208{
209 #[inline]
210 fn from(value: W) -> Self {
211 Self {
212 weave: value,
213 count: WeaveActionCount::default(),
214 _phantom_k: PhantomData,
215 _phantom_n: PhantomData,
216 _phantom_t: PhantomData,
217 }
218 }
219}
220
221impl<W, K, N, T> CountedWeave<W, K, N, T>
222where
223 W: Weave<K, N, T>,
224 K: Hash + Copy + Eq + Ord,
225 N: Node<K, T>,
226{
227 #[inline]
229 pub const fn new(weave: W, count: WeaveActionCount) -> Self {
230 Self {
231 weave,
232 count,
233 _phantom_k: PhantomData,
234 _phantom_n: PhantomData,
235 _phantom_t: PhantomData,
236 }
237 }
238 pub fn from_weave(weave: W) -> Self {
240 Self::new(weave, WeaveActionCount::new())
241 }
242 #[inline]
244 pub fn into_weave(self) -> W {
245 self.weave
246 }
247 #[inline]
249 pub const fn as_weave(&self) -> &W {
250 &self.weave
251 }
252 #[inline]
254 pub const fn as_count(&self) -> &WeaveActionCount {
255 &self.count
256 }
257 #[inline]
259 pub fn reset_count(&mut self) {
260 self.count.reset();
261 }
262}
263
264#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
269#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
270#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
271#[allow(clippy::doc_paragraphs_missing_punctuation, reason = "False positive")]
272#[non_exhaustive]
273#[must_use]
274pub struct WeaveActionCount {
275 pub add_node: usize,
277 pub set_node_active_status: usize,
279 pub set_node_bookmarked_status: usize,
281 pub remove_node: usize,
283 pub remove_all_nodes: usize,
285 pub metadata_mut: usize,
287 pub sort_node_children: usize,
289 pub sort_roots: usize,
291 pub sort_bookmarks: usize,
293 pub set_active_path: usize,
295 pub move_node: usize,
297 pub get_contents_mut: usize,
299 pub split_node: usize,
301 pub merge_with_parent: usize,
303 pub other: usize,
305}
306
307impl WeaveActionCount {
308 #[inline]
310 pub fn new() -> Self {
311 Self::default()
312 }
313 #[inline]
315 pub fn reset(&mut self) {
316 *self = Self::default();
317 }
318 #[must_use]
320 pub const fn total_count(&self) -> usize {
321 self.add_node
322 .saturating_add(self.set_node_active_status)
323 .saturating_add(self.set_node_bookmarked_status)
324 .saturating_add(self.remove_node)
325 .saturating_add(self.remove_all_nodes)
326 .saturating_add(self.metadata_mut)
327 .saturating_add(self.sort_node_children)
328 .saturating_add(self.sort_roots)
329 .saturating_add(self.sort_bookmarks)
330 .saturating_add(self.set_active_path)
331 .saturating_add(self.move_node)
332 .saturating_add(self.get_contents_mut)
333 .saturating_add(self.split_node)
334 .saturating_add(self.merge_with_parent)
335 .saturating_add(self.other)
336 }
337 pub const fn increment<K, N, T, M>(&mut self, action: &WeaveAction<K, N, T, M>)
339 where
340 K: Hash + Copy + Eq + Ord,
341 N: Node<K, T>,
342 {
343 match action {
344 WeaveAction::AddNode(_node) => self.add_node = self.add_node.saturating_add(1),
345 WeaveAction::SetNodeActiveStatus { .. } => {
346 self.set_node_active_status = self.set_node_active_status.saturating_add(1);
347 }
348 WeaveAction::SetNodeBookmarkedStatus { .. } => {
349 self.set_node_bookmarked_status = self.set_node_bookmarked_status.saturating_add(1);
350 }
351 WeaveAction::RemoveNode(_id) => self.remove_node = self.remove_node.saturating_add(1),
352 WeaveAction::RemoveAllNodes => {
353 self.remove_all_nodes = self.remove_all_nodes.saturating_add(1);
354 }
355 WeaveAction::SetMetadata(_metadata) => {
356 self.metadata_mut = self.metadata_mut.saturating_add(1);
357 }
358 WeaveAction::SetNodeChildOrdering { parent, .. } => match parent {
359 Some(_id) => self.sort_node_children = self.sort_node_children.saturating_add(1),
360 None => self.sort_roots = self.sort_roots.saturating_add(1),
361 },
362 WeaveAction::SetBookmarkOrdering(_ids) => {
363 self.sort_bookmarks = self.sort_bookmarks.saturating_add(1);
364 }
365 WeaveAction::SetActivePath(_) => {
366 self.set_active_path = self.set_active_path.saturating_add(1);
367 }
368 WeaveAction::MoveNode { .. } => self.move_node = self.move_node.saturating_add(1),
369 WeaveAction::SetNodeContent { .. } => {
370 self.get_contents_mut = self.get_contents_mut.saturating_add(1);
371 }
372 WeaveAction::SplitNode { .. } => self.split_node = self.split_node.saturating_add(1),
373 WeaveAction::MergeNodeWithParent(_id) => {
374 self.merge_with_parent = self.merge_with_parent.saturating_add(1);
375 }
376 }
377 }
378 pub const fn decrement<K, N, T, M>(&mut self, action: &WeaveAction<K, N, T, M>)
380 where
381 K: Hash + Copy + Eq + Ord,
382 N: Node<K, T>,
383 {
384 match action {
385 WeaveAction::AddNode(_node) => self.add_node = self.add_node.saturating_sub(1),
386 WeaveAction::SetNodeActiveStatus { .. } => {
387 self.set_node_active_status = self.set_node_active_status.saturating_sub(1);
388 }
389 WeaveAction::SetNodeBookmarkedStatus { .. } => {
390 self.set_node_bookmarked_status = self.set_node_bookmarked_status.saturating_sub(1);
391 }
392 WeaveAction::RemoveNode(_id) => self.remove_node = self.remove_node.saturating_sub(1),
393 WeaveAction::RemoveAllNodes => {
394 self.remove_all_nodes = self.remove_all_nodes.saturating_sub(1);
395 }
396 WeaveAction::SetMetadata(_metadata) => {
397 self.metadata_mut = self.metadata_mut.saturating_sub(1);
398 }
399 WeaveAction::SetNodeChildOrdering { parent, .. } => match parent {
400 Some(_id) => self.sort_node_children = self.sort_node_children.saturating_sub(1),
401 None => self.sort_roots = self.sort_roots.saturating_sub(1),
402 },
403 WeaveAction::SetBookmarkOrdering(_ids) => {
404 self.sort_bookmarks = self.sort_bookmarks.saturating_sub(1);
405 }
406 WeaveAction::SetActivePath(_) => {
407 self.set_active_path = self.set_active_path.saturating_sub(1);
408 }
409 WeaveAction::MoveNode { .. } => self.move_node = self.move_node.saturating_sub(1),
410 WeaveAction::SetNodeContent { .. } => {
411 self.get_contents_mut = self.get_contents_mut.saturating_sub(1);
412 }
413 WeaveAction::SplitNode { .. } => self.split_node = self.split_node.saturating_sub(1),
414 WeaveAction::MergeNodeWithParent(_id) => {
415 self.merge_with_parent = self.merge_with_parent.saturating_sub(1);
416 }
417 }
418 }
419}
420
421pub trait ActionableWeave<K, N, T, M, S>
423where
424 K: Hash + Copy + Eq + Ord,
425 N: Node<K, T>,
426 S: BuildHasher + Default + Clone,
427{
428 fn apply(&mut self, action: WeaveAction<K, N, T, M>);
434}
435
436impl<K, T, M, S> ActionableWeave<K, dependent::DependentNode<K, T, S>, T, M, S>
534 for dependent::DependentWeave<K, T, M, S>
535where
536 K: Hash + Copy + Eq + Ord,
537 T: IndependentContents + DiscreteContents,
538 S: BuildHasher + Default + Clone,
539{
540 #[allow(clippy::panic, reason = "Necessary due to API shape")]
541 fn apply(&mut self, action: WeaveAction<K, dependent::DependentNode<K, T, S>, T, M>) {
542 match action {
543 WeaveAction::AddNode(node) => {
544 assert!(self.add_node(node), "Failed to apply Weave action");
545 }
546 WeaveAction::SetNodeActiveStatus { id, value } => {
547 assert!(
548 self.set_node_active_status(&id, value),
549 "Failed to apply Weave action"
550 );
551 }
552 WeaveAction::SetNodeBookmarkedStatus { id, value } => {
553 assert!(
554 self.set_node_bookmarked_status(&id, value),
555 "Failed to apply Weave action"
556 );
557 }
558 WeaveAction::RemoveNode(id) => assert!(
559 self.remove_node(&id).is_some(),
560 "Failed to apply Weave action"
561 ),
562 WeaveAction::RemoveAllNodes => self.remove_all_nodes(),
563 WeaveAction::SetMetadata(metadata) => {
564 self.metadata_mut(|m| *m = metadata);
565 }
566 WeaveAction::SetNodeChildOrdering { parent, children } => {
567 let mut id_mapping =
568 HashMap::with_capacity_and_hasher(children.len(), S::default());
569 id_mapping.extend(
570 children
571 .into_iter()
572 .enumerate()
573 .map(|(index, id)| (id, index)),
574 );
575
576 match parent {
577 Some(id) => {
578 assert!(
579 self.sort_node_children_by_id(&id, |a, b| {
580 id_mapping[a].cmp(&id_mapping[b])
581 }),
582 "Failed to apply Weave action"
583 );
584 }
585 None => {
586 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
587 }
588 }
589 }
590 WeaveAction::SetBookmarkOrdering(ids) => {
591 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
592 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
593
594 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
595 }
596 WeaveAction::SetActivePath(_) => {
597 panic!("Weave does not implement set_active_path()");
598 }
599 WeaveAction::MoveNode { .. } => {
600 panic!("Weave does not implement move_node()");
601 }
602 WeaveAction::SetNodeContent { id, contents } => {
603 assert!(
604 self.get_contents_mut(&id, |c| *c = contents).is_some(),
605 "Failed to apply Weave action"
606 );
607 }
608 WeaveAction::SplitNode { id, at, new_id } => assert!(
609 self.split_node(&id, at, new_id),
610 "Failed to apply Weave action"
611 ),
612 WeaveAction::MergeNodeWithParent(id) => assert!(
613 self.merge_with_parent(&id).is_some(),
614 "Failed to apply Weave action"
615 ),
616 }
617 }
618}
619
620impl<K, T, M, S> ActionableWeave<K, independent::IndependentNode<K, T, S>, T, M, S>
622 for independent::IndependentWeave<K, T, M, S>
623where
624 K: Hash + Copy + Eq + Ord,
625 T: IndependentContents + DiscreteContents,
626 S: BuildHasher + Default + Clone,
627{
628 fn apply(&mut self, action: WeaveAction<K, independent::IndependentNode<K, T, S>, T, M>) {
629 match action {
630 WeaveAction::AddNode(node) => {
631 assert!(self.add_node(node), "Failed to apply Weave action");
632 }
633 WeaveAction::SetNodeActiveStatus { id, value } => {
634 assert!(
635 self.set_node_active_status(&id, value),
636 "Failed to apply Weave action"
637 );
638 }
639 WeaveAction::SetNodeBookmarkedStatus { id, value } => {
640 assert!(
641 self.set_node_bookmarked_status(&id, value),
642 "Failed to apply Weave action"
643 );
644 }
645 WeaveAction::RemoveNode(id) => assert!(
646 self.remove_node(&id).is_some(),
647 "Failed to apply Weave action"
648 ),
649 WeaveAction::RemoveAllNodes => self.remove_all_nodes(),
650 WeaveAction::SetMetadata(metadata) => {
651 self.metadata_mut(|m| *m = metadata);
652 }
653 WeaveAction::SetNodeChildOrdering { parent, children } => {
654 let mut id_mapping =
655 HashMap::with_capacity_and_hasher(children.len(), S::default());
656 id_mapping.extend(
657 children
658 .into_iter()
659 .enumerate()
660 .map(|(index, id)| (id, index)),
661 );
662
663 match parent {
664 Some(id) => {
665 assert!(
666 self.sort_node_children_by_id(&id, |a, b| {
667 id_mapping[a].cmp(&id_mapping[b])
668 }),
669 "Failed to apply Weave action"
670 );
671 }
672 None => {
673 self.sort_roots_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
674 }
675 }
676 }
677 WeaveAction::SetBookmarkOrdering(ids) => {
678 let mut id_mapping = HashMap::with_capacity_and_hasher(ids.len(), S::default());
679 id_mapping.extend(ids.into_iter().enumerate().map(|(index, id)| (id, index)));
680
681 self.sort_bookmarks_by_id(|a, b| id_mapping[a].cmp(&id_mapping[b]));
682 }
683 WeaveAction::SetActivePath(active) => {
684 self.set_active_path(active.into_iter());
685 }
686 WeaveAction::MoveNode { id, new_parents } => assert!(
687 self.move_node(&id, &new_parents),
688 "Failed to apply Weave action"
689 ),
690 WeaveAction::SetNodeContent { id, contents } => {
691 assert!(
692 self.get_contents_mut(&id, |c| *c = contents).is_some(),
693 "Failed to apply Weave action"
694 );
695 }
696 WeaveAction::SplitNode { id, at, new_id } => assert!(
697 self.split_node(&id, at, new_id),
698 "Failed to apply Weave action"
699 ),
700 WeaveAction::MergeNodeWithParent(id) => assert!(
701 self.merge_with_parent(&id).is_some(),
702 "Failed to apply Weave action"
703 ),
704 }
705 }
706}
707
708impl<W, K, N, T, M> Weave<K, N, T> for LoggedWeave<W, K, N, T, M>
709where
710 W: Weave<K, N, T>,
711 K: Hash + Copy + Eq + Ord,
712 N: Node<K, T> + Clone,
713{
714 type Nodes = W::Nodes;
715 type Roots = W::Roots;
716
717 #[inline]
718 fn len(&self) -> usize {
719 self.weave.len()
720 }
721 #[inline]
722 fn is_empty(&self) -> bool {
723 self.weave.is_empty()
724 }
725 #[inline]
726 fn nodes(&self) -> &Self::Nodes {
727 self.weave.nodes()
728 }
729 #[inline]
730 fn roots(&self) -> &Self::Roots {
731 self.weave.roots()
732 }
733 #[inline]
734 fn contains(&self, id: &K) -> bool {
735 self.weave.contains(id)
736 }
737 #[inline]
738 fn contains_active(&self, id: &K) -> bool {
739 self.weave.contains_active(id)
740 }
741 #[inline]
742 fn get_node(&self, id: &K) -> Option<&N> {
743 self.weave.get_node(id)
744 }
745 #[inline]
746 fn get_node_parents(&self, id: &K) -> Option<&N::From> {
747 self.weave.get_node_parents(id)
748 }
749 #[inline]
750 fn get_node_children(&self, id: &K) -> Option<&N::To> {
751 self.weave.get_node_children(id)
752 }
753 #[inline]
754 fn get_ordered_node_identifiers(&mut self, output: &mut Vec<K>) {
755 self.weave.get_ordered_node_identifiers(output);
756 }
757 #[inline]
758 fn get_ordered_node_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
759 self.weave.get_ordered_node_identifiers_from(id, output);
760 }
761 #[inline]
762 fn get_active_path(&mut self, output: &mut Vec<K>) {
763 self.weave.get_active_path(output);
764 }
765 #[inline]
766 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
767 self.weave.get_path_from(id, output);
768 }
769 fn add_node(&mut self, node: N) -> bool {
770 if self.weave.add_node(node.clone()) {
771 self.actions.push_back(WeaveAction::AddNode(node));
772 true
773 } else {
774 false
775 }
776 }
777 fn set_node_active_status(&mut self, id: &K, value: bool) -> bool {
778 if self.weave.set_node_active_status(id, value) {
779 self.actions
780 .push_back(WeaveAction::SetNodeActiveStatus { id: *id, value });
781 true
782 } else {
783 false
784 }
785 }
786 fn remove_node(&mut self, id: &K) -> Option<N> {
787 if let Some(removed) = self.weave.remove_node(id) {
788 self.actions.push_back(WeaveAction::RemoveNode(*id));
789 Some(removed)
790 } else {
791 None
792 }
793 }
794 fn remove_node_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
795 if self.weave.remove_node_tracked(id, on_removal) {
796 self.actions.push_back(WeaveAction::RemoveNode(*id));
797 true
798 } else {
799 false
800 }
801 }
802 fn remove_all_nodes(&mut self) {
803 self.weave.remove_all_nodes();
804 self.actions.push_back(WeaveAction::RemoveAllNodes);
805 }
806}
807
808impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for LoggedWeave<W, K, N, T, M>
809where
810 W: MetadataWeave<K, N, T, M>,
811 K: Hash + Copy + Eq + Ord,
812 N: Node<K, T> + Clone,
813 M: Clone,
814{
815 #[inline]
816 fn metadata(&self) -> &M {
817 self.weave.metadata()
818 }
819 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
820 self.weave.metadata_mut(|metadata| {
821 let output = callback(metadata);
822
823 self.actions
824 .push_back(WeaveAction::SetMetadata(metadata.clone()));
825
826 output
827 })
828 }
829}
830
831impl<W, K, N, T, M> BookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
832where
833 W: BookmarkableWeave<K, N, T>,
834 K: Hash + Copy + Eq + Ord,
835 N: Node<K, T> + Clone,
836{
837 type Bookmarks = W::Bookmarks;
838
839 #[inline]
840 fn bookmarks(&self) -> &Self::Bookmarks {
841 self.weave.bookmarks()
842 }
843 #[inline]
844 fn contains_bookmark(&self, id: &K) -> bool {
845 self.weave.contains_bookmark(id)
846 }
847 fn set_node_bookmarked_status(&mut self, id: &K, value: bool) -> bool {
848 if self.weave.set_node_bookmarked_status(id, value) {
849 self.actions
850 .push_back(WeaveAction::SetNodeBookmarkedStatus { id: *id, value });
851 true
852 } else {
853 false
854 }
855 }
856}
857
858impl<W, K, N, T, M> SortableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
859where
860 W: SortableWeave<K, N, T>,
861 K: Hash + Copy + Eq + Ord,
862 N: Node<K, T> + Clone,
863 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
864 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
865{
866 fn sort_node_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
867 if self.weave.sort_node_children_by(id, cmp) {
868 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
869 parent: Some(*id),
870 children: self
871 .weave
872 .get_node(id)
873 .unwrap()
874 .to()
875 .into_iter()
876 .copied()
877 .collect(),
878 });
879 true
880 } else {
881 false
882 }
883 }
884 fn sort_node_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
885 if self.weave.sort_node_children_by_id(id, cmp) {
886 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
887 parent: Some(*id),
888 children: self
889 .weave
890 .get_node(id)
891 .unwrap()
892 .to()
893 .into_iter()
894 .copied()
895 .collect(),
896 });
897 true
898 } else {
899 false
900 }
901 }
902 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
903 self.weave.sort_roots_by(cmp);
904 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
905 parent: None,
906 children: self.weave.roots().into_iter().copied().collect(),
907 });
908 }
909 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
910 self.weave.sort_roots_by_id(cmp);
911 self.actions.push_back(WeaveAction::SetNodeChildOrdering {
912 parent: None,
913 children: self.weave.roots().into_iter().copied().collect(),
914 });
915 }
916}
917
918impl<W, K, N, T, M> SortableBookmarkableWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
919where
920 W: SortableBookmarkableWeave<K, N, T>,
921 K: Hash + Copy + Eq + Ord,
922 N: Node<K, T> + Clone,
923 for<'a> &'a N::To: IntoIterator<Item = &'a K>,
924 for<'a> &'a W::Roots: IntoIterator<Item = &'a K>,
925 for<'a> &'a W::Bookmarks: IntoIterator<Item = &'a K>,
926{
927 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
928 self.weave.sort_bookmarks_by(cmp);
929 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
930 self.weave.bookmarks().into_iter().copied().collect(),
931 ));
932 }
933 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
934 self.weave.sort_bookmarks_by_id(cmp);
935 self.actions.push_back(WeaveAction::SetBookmarkOrdering(
936 self.weave.bookmarks().into_iter().copied().collect(),
937 ));
938 }
939}
940
941impl<W, K, N, T, M> ActiveSingularWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
942where
943 W: ActiveSingularWeave<K, N, T>,
944 K: Hash + Copy + Eq + Ord,
945 N: Node<K, T> + Clone,
946{
947 #[inline]
948 fn active(&self) -> Option<K> {
949 self.weave.active()
950 }
951}
952
953impl<W, K, N, T, M> ActivePathWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
954where
955 W: ActivePathWeave<K, N, T>,
956 K: Hash + Copy + Eq + Ord,
957 N: Node<K, T> + Clone,
958{
959 type Active = W::Active;
960
961 #[inline]
962 fn active(&self) -> &Self::Active {
963 self.weave.active()
964 }
965 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
966 let active: Vec<K> = active.collect();
967
968 self.weave.set_active_path(active.iter().copied());
969 self.actions.push_back(WeaveAction::SetActivePath(active));
970 }
971}
972
973impl<W, K, N, T, M> IndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
974where
975 W: IndependentWeave<K, N, T>,
976 K: Hash + Copy + Eq + Ord,
977 N: Node<K, T> + Clone,
978 T: IndependentContents + Clone,
979{
980 fn move_node(&mut self, id: &K, new_parents: &[K]) -> bool {
981 if self.weave.move_node(id, new_parents) {
982 self.actions.push_back(WeaveAction::MoveNode {
983 id: *id,
984 new_parents: new_parents.to_vec(),
985 });
986 true
987 } else {
988 false
989 }
990 }
991}
992
993impl<W, K, N, T, M> SemiIndependentWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
994where
995 W: SemiIndependentWeave<K, N, T>,
996 K: Hash + Copy + Eq + Ord,
997 N: Node<K, T> + Clone,
998 T: IndependentContents + Clone,
999{
1000 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1001 self.weave.get_contents_mut(id, |contents| {
1002 let output = callback(contents);
1003
1004 self.actions.push_back(WeaveAction::SetNodeContent {
1005 id: *id,
1006 contents: contents.clone(),
1007 });
1008
1009 output
1010 })
1011 }
1012}
1013
1014impl<W, K, N, T, M> DiscreteWeave<K, N, T> for LoggedWeave<W, K, N, T, M>
1015where
1016 W: DiscreteWeave<K, N, T>,
1017 K: Hash + Copy + Eq + Ord,
1018 N: Node<K, T> + Clone,
1019 T: DiscreteContents,
1020{
1021 fn split_node(&mut self, id: &K, at: usize, new_id: K) -> bool {
1022 if self.weave.split_node(id, at, new_id) {
1023 self.actions.push_back(WeaveAction::SplitNode {
1024 id: *id,
1025 at,
1026 new_id,
1027 });
1028 true
1029 } else {
1030 false
1031 }
1032 }
1033 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1034 match self.weave.merge_with_parent(id) {
1035 Some(new_id) => {
1036 self.actions
1037 .push_back(WeaveAction::MergeNodeWithParent(*id));
1038 Some(new_id)
1039 }
1040 None => None,
1041 }
1042 }
1043}
1044
1045impl<W, K, N, T> Weave<K, N, T> for CountedWeave<W, K, N, T>
1046where
1047 W: Weave<K, N, T>,
1048 K: Hash + Copy + Eq + Ord,
1049 N: Node<K, T>,
1050{
1051 type Nodes = W::Nodes;
1052 type Roots = W::Roots;
1053
1054 #[inline]
1055 fn len(&self) -> usize {
1056 self.weave.len()
1057 }
1058 #[inline]
1059 fn is_empty(&self) -> bool {
1060 self.weave.is_empty()
1061 }
1062 #[inline]
1063 fn nodes(&self) -> &Self::Nodes {
1064 self.weave.nodes()
1065 }
1066 #[inline]
1067 fn roots(&self) -> &Self::Roots {
1068 self.weave.roots()
1069 }
1070 #[inline]
1071 fn contains(&self, id: &K) -> bool {
1072 self.weave.contains(id)
1073 }
1074 #[inline]
1075 fn contains_active(&self, id: &K) -> bool {
1076 self.weave.contains_active(id)
1077 }
1078 #[inline]
1079 fn get_node(&self, id: &K) -> Option<&N> {
1080 self.weave.get_node(id)
1081 }
1082 #[inline]
1083 fn get_node_parents(&self, id: &K) -> Option<&N::From> {
1084 self.weave.get_node_parents(id)
1085 }
1086 #[inline]
1087 fn get_node_children(&self, id: &K) -> Option<&N::To> {
1088 self.weave.get_node_children(id)
1089 }
1090 #[inline]
1091 fn get_ordered_node_identifiers(&mut self, output: &mut Vec<K>) {
1092 self.weave.get_ordered_node_identifiers(output);
1093 }
1094 #[inline]
1095 fn get_ordered_node_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
1096 self.weave.get_ordered_node_identifiers_from(id, output);
1097 }
1098 #[inline]
1099 fn get_active_path(&mut self, output: &mut Vec<K>) {
1100 self.weave.get_active_path(output);
1101 }
1102 #[inline]
1103 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
1104 self.weave.get_path_from(id, output);
1105 }
1106 #[inline]
1107 fn add_node(&mut self, node: N) -> bool {
1108 if self.weave.add_node(node) {
1109 self.count.add_node = self.count.add_node.saturating_add(1);
1110 true
1111 } else {
1112 false
1113 }
1114 }
1115 #[inline]
1116 fn set_node_active_status(&mut self, id: &K, value: bool) -> bool {
1117 if self.weave.set_node_active_status(id, value) {
1118 self.count.set_node_active_status = self.count.set_node_active_status.saturating_add(1);
1119 true
1120 } else {
1121 false
1122 }
1123 }
1124 #[inline]
1125 fn remove_node(&mut self, id: &K) -> Option<N> {
1126 if let Some(removed) = self.weave.remove_node(id) {
1127 self.count.remove_node = self.count.remove_node.saturating_add(1);
1128 Some(removed)
1129 } else {
1130 None
1131 }
1132 }
1133 #[inline]
1134 fn remove_node_tracked(&mut self, id: &K, on_removal: impl FnMut(N)) -> bool {
1135 if self.weave.remove_node_tracked(id, on_removal) {
1136 self.count.remove_node = self.count.remove_node.saturating_add(1);
1137 true
1138 } else {
1139 false
1140 }
1141 }
1142 #[inline]
1143 fn remove_all_nodes(&mut self) {
1144 self.weave.remove_all_nodes();
1145 self.count.remove_all_nodes = self.count.remove_all_nodes.saturating_add(1);
1146 }
1147}
1148
1149impl<W, K, N, T, M> MetadataWeave<K, N, T, M> for CountedWeave<W, K, N, T>
1150where
1151 W: MetadataWeave<K, N, T, M>,
1152 K: Hash + Copy + Eq + Ord,
1153 N: Node<K, T>,
1154{
1155 #[inline]
1156 fn metadata(&self) -> &M {
1157 self.weave.metadata()
1158 }
1159 #[inline]
1160 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
1161 self.weave.metadata_mut(|metadata| {
1162 let output = callback(metadata);
1163 self.count.metadata_mut = self.count.metadata_mut.saturating_add(1);
1164 output
1165 })
1166 }
1167}
1168
1169impl<W, K, N, T> BookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1170where
1171 W: BookmarkableWeave<K, N, T>,
1172 K: Hash + Copy + Eq + Ord,
1173 N: Node<K, T>,
1174{
1175 type Bookmarks = W::Bookmarks;
1176
1177 #[inline]
1178 fn bookmarks(&self) -> &Self::Bookmarks {
1179 self.weave.bookmarks()
1180 }
1181 #[inline]
1182 fn contains_bookmark(&self, id: &K) -> bool {
1183 self.weave.contains_bookmark(id)
1184 }
1185 #[inline]
1186 fn set_node_bookmarked_status(&mut self, id: &K, value: bool) -> bool {
1187 if self.weave.set_node_bookmarked_status(id, value) {
1188 self.count.set_node_bookmarked_status =
1189 self.count.set_node_bookmarked_status.saturating_add(1);
1190 true
1191 } else {
1192 false
1193 }
1194 }
1195}
1196
1197impl<W, K, N, T> SortableWeave<K, N, T> for CountedWeave<W, K, N, T>
1198where
1199 W: SortableWeave<K, N, T>,
1200 K: Hash + Copy + Eq + Ord,
1201 N: Node<K, T>,
1202{
1203 #[inline]
1204 fn sort_node_children_by(&mut self, id: &K, cmp: impl FnMut(&N, &N) -> Ordering) -> bool {
1205 if self.weave.sort_node_children_by(id, cmp) {
1206 self.count.sort_node_children = self.count.sort_node_children.saturating_add(1);
1207 true
1208 } else {
1209 false
1210 }
1211 }
1212 #[inline]
1213 fn sort_node_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
1214 if self.weave.sort_node_children_by_id(id, cmp) {
1215 self.count.sort_node_children = self.count.sort_node_children.saturating_add(1);
1216 true
1217 } else {
1218 false
1219 }
1220 }
1221 #[inline]
1222 fn sort_roots_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1223 self.weave.sort_roots_by(cmp);
1224 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1225 }
1226 #[inline]
1227 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1228 self.weave.sort_roots_by_id(cmp);
1229 self.count.sort_roots = self.count.sort_roots.saturating_add(1);
1230 }
1231}
1232
1233impl<W, K, N, T> SortableBookmarkableWeave<K, N, T> for CountedWeave<W, K, N, T>
1234where
1235 W: SortableBookmarkableWeave<K, N, T>,
1236 K: Hash + Copy + Eq + Ord,
1237 N: Node<K, T>,
1238{
1239 #[inline]
1240 fn sort_bookmarks_by(&mut self, cmp: impl FnMut(&N, &N) -> Ordering) {
1241 self.weave.sort_bookmarks_by(cmp);
1242 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1243 }
1244 #[inline]
1245 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1246 self.weave.sort_bookmarks_by_id(cmp);
1247 self.count.sort_bookmarks = self.count.sort_bookmarks.saturating_add(1);
1248 }
1249}
1250
1251impl<W, K, N, T> ActiveSingularWeave<K, N, T> for CountedWeave<W, K, N, T>
1252where
1253 W: ActiveSingularWeave<K, N, T>,
1254 K: Hash + Copy + Eq + Ord,
1255 N: Node<K, T>,
1256{
1257 #[inline]
1258 fn active(&self) -> Option<K> {
1259 self.weave.active()
1260 }
1261}
1262
1263impl<W, K, N, T> ActivePathWeave<K, N, T> for CountedWeave<W, K, N, T>
1264where
1265 W: ActivePathWeave<K, N, T>,
1266 K: Hash + Copy + Eq + Ord,
1267 N: Node<K, T>,
1268{
1269 type Active = W::Active;
1270
1271 #[inline]
1272 fn active(&self) -> &Self::Active {
1273 self.weave.active()
1274 }
1275 #[inline]
1276 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
1277 self.weave.set_active_path(active);
1278 self.count.set_active_path = self.count.set_active_path.saturating_add(1);
1279 }
1280}
1281
1282impl<W, K, N, T> IndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1283where
1284 W: IndependentWeave<K, N, T>,
1285 K: Hash + Copy + Eq + Ord,
1286 N: Node<K, T>,
1287 T: IndependentContents,
1288{
1289 #[inline]
1290 fn move_node(&mut self, id: &K, new_parents: &[K]) -> bool {
1291 if self.weave.move_node(id, new_parents) {
1292 self.count.move_node = self.count.move_node.saturating_add(1);
1293 true
1294 } else {
1295 false
1296 }
1297 }
1298}
1299
1300impl<W, K, N, T> SemiIndependentWeave<K, N, T> for CountedWeave<W, K, N, T>
1301where
1302 W: SemiIndependentWeave<K, N, T>,
1303 K: Hash + Copy + Eq + Ord,
1304 N: Node<K, T>,
1305 T: IndependentContents,
1306{
1307 #[inline]
1308 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1309 self.weave.get_contents_mut(id, |contents| {
1310 let output = callback(contents);
1311 self.count.get_contents_mut = self.count.get_contents_mut.saturating_add(1);
1312 output
1313 })
1314 }
1315}
1316
1317impl<W, K, N, T> DiscreteWeave<K, N, T> for CountedWeave<W, K, N, T>
1318where
1319 W: DiscreteWeave<K, N, T>,
1320 K: Hash + Copy + Eq + Ord,
1321 N: Node<K, T>,
1322 T: DiscreteContents,
1323{
1324 #[inline]
1325 fn split_node(&mut self, id: &K, at: usize, new_id: K) -> bool {
1326 if self.weave.split_node(id, at, new_id) {
1327 self.count.split_node = self.count.split_node.saturating_add(1);
1328 true
1329 } else {
1330 false
1331 }
1332 }
1333 #[inline]
1334 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1335 match self.weave.merge_with_parent(id) {
1336 Some(new_id) => {
1337 self.count.merge_with_parent = self.count.merge_with_parent.saturating_add(1);
1338 Some(new_id)
1339 }
1340 None => None,
1341 }
1342 }
1343}