1use crate::block::{EmbedPrelim, ItemContent, ItemPtr, Prelim, Unused};
2use crate::block_iter::BlockIter;
3use crate::encoding::read::Error;
4use crate::encoding::serde::from_any;
5use crate::moving::StickyIndex;
6use crate::transaction::TransactionMut;
7use crate::types::{
8 event_change_set, AsPrelim, Branch, BranchPtr, Change, ChangeSet, DefaultPrelim, In, Out, Path,
9 RootRef, SharedRef, ToJson, TypeRef,
10};
11use crate::{Any, Assoc, DeepObservable, IndexedSequence, Observable, ReadTxn, ID};
12use serde::de::DeserializeOwned;
13use std::borrow::Borrow;
14use std::cell::UnsafeCell;
15use std::collections::HashSet;
16use std::convert::{TryFrom, TryInto};
17use std::iter::FromIterator;
18use std::marker::PhantomData;
19use std::ops::{Deref, DerefMut};
20
21#[repr(transparent)]
76#[derive(Debug, Clone)]
77pub struct ArrayRef(BranchPtr);
78
79impl RootRef for ArrayRef {
80 fn type_ref() -> TypeRef {
81 TypeRef::Array
82 }
83}
84impl SharedRef for ArrayRef {}
85impl Array for ArrayRef {}
86impl IndexedSequence for ArrayRef {}
87
88#[cfg(feature = "weak")]
89impl crate::Quotable for ArrayRef {}
90
91impl ToJson for ArrayRef {
92 fn to_json<T: ReadTxn>(&self, txn: &T) -> Any {
93 let mut walker = BlockIter::new(self.0);
94 let len = self.0.len();
95 let mut buf = vec![Out::default(); len as usize];
96 let read = walker.slice(txn, &mut buf);
97 if read == len {
98 let res = buf.into_iter().map(|v| v.to_json(txn)).collect();
99 Any::Array(res)
100 } else {
101 panic!(
102 "Defect: Array::to_json didn't read all elements ({}/{})",
103 read, len
104 )
105 }
106 }
107}
108
109impl Eq for ArrayRef {}
110impl PartialEq for ArrayRef {
111 fn eq(&self, other: &Self) -> bool {
112 self.0.id() == other.0.id()
113 }
114}
115
116impl AsRef<Branch> for ArrayRef {
117 fn as_ref(&self) -> &Branch {
118 self.0.deref()
119 }
120}
121
122impl DeepObservable for ArrayRef {}
123impl Observable for ArrayRef {
124 type Event = ArrayEvent;
125}
126
127impl TryFrom<ItemPtr> for ArrayRef {
128 type Error = ItemPtr;
129
130 fn try_from(value: ItemPtr) -> Result<Self, Self::Error> {
131 if let Some(branch) = value.clone().as_branch() {
132 Ok(ArrayRef::from(branch))
133 } else {
134 Err(value)
135 }
136 }
137}
138
139impl TryFrom<Out> for ArrayRef {
140 type Error = Out;
141
142 fn try_from(value: Out) -> Result<Self, Self::Error> {
143 match value {
144 Out::YArray(value) => Ok(value),
145 other => Err(other),
146 }
147 }
148}
149
150impl AsPrelim for ArrayRef {
151 type Prelim = ArrayPrelim;
152
153 fn as_prelim<T: ReadTxn>(&self, txn: &T) -> Self::Prelim {
154 let mut prelim = Vec::with_capacity(self.len(txn) as usize);
155 for value in self.iter(txn) {
156 prelim.push(value.as_prelim(txn));
157 }
158 ArrayPrelim(prelim)
159 }
160}
161
162impl DefaultPrelim for ArrayRef {
163 type Prelim = ArrayPrelim;
164
165 #[inline]
166 fn default_prelim() -> Self::Prelim {
167 ArrayPrelim::default()
168 }
169}
170
171pub trait Array: AsRef<Branch> + Sized {
172 fn len<T: ReadTxn>(&self, _txn: &T) -> u32 {
174 self.as_ref().len()
175 }
176
177 fn insert<V>(&self, txn: &mut TransactionMut, index: u32, value: V) -> V::Return
187 where
188 V: Prelim,
189 {
190 let mut walker = BlockIter::new(BranchPtr::from(self.as_ref()));
191 if walker.try_forward(txn, index) {
192 let ptr = walker
193 .insert_contents(txn, value)
194 .expect("cannot insert empty value");
195 if let Ok(integrated) = ptr.try_into() {
196 integrated
197 } else {
198 panic!("Defect: unexpected integrated type")
199 }
200 } else {
201 panic!("Index {} is outside of the range of an array", index);
202 }
203 }
204
205 fn insert_range<T, V>(&self, txn: &mut TransactionMut, index: u32, values: T)
213 where
214 T: IntoIterator<Item = V>,
215 V: Into<Any>,
216 {
217 let prelim = RangePrelim::new(values);
218 if !prelim.is_empty() {
219 self.insert(txn, index, prelim);
220 }
221 }
222
223 fn push_back<V>(&self, txn: &mut TransactionMut, value: V) -> V::Return
227 where
228 V: Prelim,
229 {
230 let len = self.len(txn);
231 self.insert(txn, len, value)
232 }
233
234 fn push_front<V>(&self, txn: &mut TransactionMut, content: V) -> V::Return
238 where
239 V: Prelim,
240 {
241 self.insert(txn, 0, content)
242 }
243
244 fn remove(&self, txn: &mut TransactionMut, index: u32) {
246 self.remove_range(txn, index, 1)
247 }
248
249 fn remove_range(&self, txn: &mut TransactionMut, index: u32, len: u32) {
254 let mut walker = BlockIter::new(BranchPtr::from(self.as_ref()));
255 if walker.try_forward(txn, index) {
256 walker.delete(txn, len)
257 } else {
258 panic!("Index {} is outside of the range of an array", index);
259 }
260 }
261
262 fn get<T: ReadTxn>(&self, txn: &T, index: u32) -> Option<Out> {
265 let mut walker = BlockIter::new(BranchPtr::from(self.as_ref()));
266 if walker.try_forward(txn, index) {
267 walker.read_value(txn)
268 } else {
269 None
270 }
271 }
272
273 fn get_as<T, V>(&self, txn: &T, index: u32) -> Result<V, Error>
327 where
328 T: ReadTxn,
329 V: DeserializeOwned,
330 {
331 let out = self.get(txn, index).unwrap_or(Out::Any(Any::Null));
332 let any = out.to_json(txn);
334 from_any(&any)
335 }
336
337 fn move_to(&self, txn: &mut TransactionMut, source: u32, target: u32) {
345 if source == target || source + 1 == target {
346 return;
348 }
349 let this = BranchPtr::from(self.as_ref());
350 let left = StickyIndex::at(txn, this, source, Assoc::After)
351 .expect("`source` index parameter is beyond the range of an y-array");
352 let mut right = left.clone();
353 right.assoc = Assoc::Before;
354 let mut walker = BlockIter::new(this);
355 if walker.try_forward(txn, target) {
356 walker.insert_move(txn, left, right);
357 } else {
358 panic!(
359 "`target` index parameter {} is outside of the range of an array",
360 target
361 );
362 }
363 }
364
365 fn move_range_to(
389 &self,
390 txn: &mut TransactionMut,
391 start: u32,
392 assoc_start: Assoc,
393 end: u32,
394 assoc_end: Assoc,
395 target: u32,
396 ) {
397 if start <= target && target <= end {
398 return;
400 }
401 let this = BranchPtr::from(self.as_ref());
402 let left = StickyIndex::at(txn, this, start, assoc_start)
403 .expect("`start` index parameter is beyond the range of an y-array");
404 let right = StickyIndex::at(txn, this, end + 1, assoc_end)
405 .expect("`end` index parameter is beyond the range of an y-array");
406 let mut walker = BlockIter::new(this);
407 if walker.try_forward(txn, target) {
408 walker.insert_move(txn, left, right);
409 } else {
410 panic!(
411 "`target` index parameter {} is outside of the range of an array",
412 target
413 );
414 }
415 }
416
417 fn iter<'a, T: ReadTxn + 'a>(&self, txn: &'a T) -> ArrayIter<&'a T, T> {
420 ArrayIter::from_ref(self.as_ref(), txn)
421 }
422}
423
424pub struct ArrayIter<B, T>
425where
426 B: Borrow<T>,
427 T: ReadTxn,
428{
429 inner: BlockIter,
430 txn: B,
431 _marker: PhantomData<T>,
432}
433
434impl<T> ArrayIter<T, T>
435where
436 T: Borrow<T> + ReadTxn,
437{
438 pub fn from(array: &ArrayRef, txn: T) -> Self {
439 ArrayIter {
440 inner: BlockIter::new(array.0),
441 txn,
442 _marker: PhantomData::default(),
443 }
444 }
445}
446
447impl<'a, T> ArrayIter<&'a T, T>
448where
449 T: Borrow<T> + ReadTxn,
450{
451 pub fn from_ref(array: &Branch, txn: &'a T) -> Self {
452 ArrayIter {
453 inner: BlockIter::new(BranchPtr::from(array)),
454 txn,
455 _marker: PhantomData::default(),
456 }
457 }
458}
459
460impl<B, T> Iterator for ArrayIter<B, T>
461where
462 B: Borrow<T>,
463 T: ReadTxn,
464{
465 type Item = Out;
466
467 fn next(&mut self) -> Option<Self::Item> {
468 if self.inner.finished() {
469 None
470 } else {
471 let mut buf = [Out::default(); 1];
472 let txn = self.txn.borrow();
473 if self.inner.slice(txn, &mut buf) != 0 {
474 Some(std::mem::replace(&mut buf[0], Out::default()))
475 } else {
476 None
477 }
478 }
479 }
480}
481
482impl From<BranchPtr> for ArrayRef {
483 fn from(inner: BranchPtr) -> Self {
484 ArrayRef(inner)
485 }
486}
487
488#[repr(transparent)]
491#[derive(Debug, Clone, PartialEq, Default)]
492pub struct ArrayPrelim(Vec<In>);
493
494impl Deref for ArrayPrelim {
495 type Target = Vec<In>;
496
497 #[inline]
498 fn deref(&self) -> &Self::Target {
499 &self.0
500 }
501}
502
503impl DerefMut for ArrayPrelim {
504 fn deref_mut(&mut self) -> &mut Self::Target {
505 &mut self.0
506 }
507}
508
509impl From<ArrayPrelim> for In {
510 #[inline]
511 fn from(value: ArrayPrelim) -> Self {
512 In::Array(value)
513 }
514}
515
516impl<T> FromIterator<T> for ArrayPrelim
517where
518 T: Into<In>,
519{
520 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
521 ArrayPrelim(iter.into_iter().map(|v| v.into()).collect())
522 }
523}
524
525impl<I, T> From<I> for ArrayPrelim
526where
527 I: IntoIterator<Item = T>,
528 T: Into<In>,
529{
530 fn from(iter: I) -> Self {
531 ArrayPrelim(iter.into_iter().map(|v| v.into()).collect())
532 }
533}
534
535impl Prelim for ArrayPrelim {
536 type Return = ArrayRef;
537
538 fn into_content(self, _txn: &mut TransactionMut) -> (ItemContent, Option<Self>) {
539 let inner = Branch::new(TypeRef::Array);
540 (ItemContent::Type(inner), Some(self))
541 }
542
543 fn integrate(self, txn: &mut TransactionMut, inner_ref: BranchPtr) {
544 let array = ArrayRef::from(inner_ref);
545 for value in self.0 {
546 array.push_back(txn, value);
547 }
548 }
549}
550
551impl Into<EmbedPrelim<ArrayPrelim>> for ArrayPrelim {
552 #[inline]
553 fn into(self) -> EmbedPrelim<ArrayPrelim> {
554 EmbedPrelim::Shared(self)
555 }
556}
557
558#[repr(transparent)]
561struct RangePrelim(Vec<Any>);
562
563impl RangePrelim {
564 fn new<I, T>(iter: I) -> Self
565 where
566 I: IntoIterator<Item = T>,
567 T: Into<Any>,
568 {
569 RangePrelim(iter.into_iter().map(|v| v.into()).collect())
570 }
571
572 #[inline]
573 fn is_empty(&self) -> bool {
574 self.0.is_empty()
575 }
576}
577
578impl Prelim for RangePrelim {
579 type Return = Unused;
580
581 fn into_content(self, _txn: &mut TransactionMut) -> (ItemContent, Option<Self>) {
582 (ItemContent::Any(self.0), None)
583 }
584
585 fn integrate(self, _txn: &mut TransactionMut, _inner_ref: BranchPtr) {}
586}
587
588pub struct ArrayEvent {
590 pub(crate) current_target: BranchPtr,
591 target: ArrayRef,
592 change_set: UnsafeCell<Option<Box<ChangeSet<Change>>>>,
593}
594
595impl ArrayEvent {
596 pub(crate) fn new(branch_ref: BranchPtr) -> Self {
597 let current_target = branch_ref.clone();
598 ArrayEvent {
599 target: ArrayRef::from(branch_ref),
600 current_target,
601 change_set: UnsafeCell::new(None),
602 }
603 }
604
605 pub fn target(&self) -> &ArrayRef {
607 &self.target
608 }
609
610 pub fn path(&self) -> Path {
612 Branch::path(self.current_target, self.target.0)
613 }
614
615 pub fn delta(&self, txn: &TransactionMut) -> &[Change] {
618 self.changes(txn).delta.as_slice()
619 }
620
621 pub fn inserts(&self, txn: &TransactionMut) -> &HashSet<ID> {
624 &self.changes(txn).added
625 }
626
627 pub fn removes(&self, txn: &TransactionMut) -> &HashSet<ID> {
630 &self.changes(txn).deleted
631 }
632
633 fn changes(&self, txn: &TransactionMut) -> &ChangeSet<Change> {
634 let change_set = unsafe { self.change_set.get().as_mut().unwrap() };
635 change_set.get_or_insert_with(|| Box::new(event_change_set(txn, self.target.0.start)))
636 }
637}
638
639#[cfg(test)]
640mod test {
641 use crate::block::ClientID;
642 use crate::test_utils::{exchange_updates, run_scenario, RngExt};
643 use crate::types::map::MapPrelim;
644 use crate::types::{Change, DeepObservable, Event, Out, Path, PathSegment, ToJson};
645 use crate::{
646 any, Any, Array, ArrayPrelim, Assoc, Doc, Map, MapRef, Observable, SharedRef, StateVector,
647 Transact, Update, WriteTxn, ID,
648 };
649 use std::collections::{HashMap, HashSet};
650 use std::iter::FromIterator;
651 use std::sync::{Arc, Mutex};
652
653 #[test]
654 fn push_back() {
655 let doc = Doc::with_client_id(1);
656 let a = doc.get_or_insert_array("array");
657 let mut txn = doc.transact_mut();
658
659 a.push_back(&mut txn, "a");
660 a.push_back(&mut txn, "b");
661 a.push_back(&mut txn, "c");
662
663 let actual: Vec<_> = a.iter(&txn).collect();
664 assert_eq!(actual, vec!["a".into(), "b".into(), "c".into()]);
665 }
666
667 #[test]
668 fn push_front() {
669 let doc = Doc::with_client_id(1);
670 let a = doc.get_or_insert_array("array");
671 let mut txn = doc.transact_mut();
672
673 a.push_front(&mut txn, "c");
674 a.push_front(&mut txn, "b");
675 a.push_front(&mut txn, "a");
676
677 let actual: Vec<_> = a.iter(&txn).collect();
678 assert_eq!(actual, vec!["a".into(), "b".into(), "c".into()]);
679 }
680
681 #[test]
682 fn insert() {
683 let doc = Doc::with_client_id(1);
684 let a = doc.get_or_insert_array("array");
685 let mut txn = doc.transact_mut();
686
687 a.insert(&mut txn, 0, "a");
688 a.insert(&mut txn, 1, "c");
689 a.insert(&mut txn, 1, "b");
690
691 let actual: Vec<_> = a.iter(&txn).collect();
692 assert_eq!(actual, vec!["a".into(), "b".into(), "c".into()]);
693 }
694
695 #[test]
696 fn basic() {
697 let d1 = Doc::with_client_id(1);
698 let d2 = Doc::with_client_id(2);
699
700 let a1 = d1.get_or_insert_array("array");
701
702 a1.insert(&mut d1.transact_mut(), 0, "Hi");
703 let update = d1
704 .transact()
705 .encode_state_as_update_v1(&StateVector::default());
706
707 let a2 = d2.get_or_insert_array("array");
708 let mut t2 = d2.transact_mut();
709 t2.apply_update(Update::decode_v1(update.as_slice()).unwrap())
710 .unwrap();
711 let actual: Vec<_> = a2.iter(&t2).collect();
712
713 assert_eq!(actual, vec!["Hi".into()]);
714 }
715
716 #[test]
717 fn len() {
718 let d = Doc::with_client_id(1);
719 let a = d.get_or_insert_array("array");
720
721 {
722 let mut txn = d.transact_mut();
723
724 a.push_back(&mut txn, 0); a.push_back(&mut txn, 1); a.push_back(&mut txn, 2); a.push_back(&mut txn, 3); a.remove_range(&mut txn, 0, 1); a.insert(&mut txn, 0, 0); assert_eq!(a.len(&txn), 4);
733 }
734 {
735 let mut txn = d.transact_mut();
736 a.remove_range(&mut txn, 1, 1); assert_eq!(a.len(&txn), 3);
738
739 a.insert(&mut txn, 1, 1); assert_eq!(a.len(&txn), 4);
741
742 a.remove_range(&mut txn, 2, 1); assert_eq!(a.len(&txn), 3);
744
745 a.insert(&mut txn, 2, 2); assert_eq!(a.len(&txn), 4);
747 }
748
749 let mut txn = d.transact_mut();
750 assert_eq!(a.len(&txn), 4);
751
752 a.remove_range(&mut txn, 1, 1);
753 assert_eq!(a.len(&txn), 3);
754
755 a.insert(&mut txn, 1, 1);
756 assert_eq!(a.len(&txn), 4);
757 }
758
759 #[test]
760 fn remove_insert() {
761 let d1 = Doc::with_client_id(1);
762 let a1 = d1.get_or_insert_array("array");
763
764 let mut t1 = d1.transact_mut();
765 a1.insert(&mut t1, 0, "A");
766 a1.remove_range(&mut t1, 1, 0);
767 }
768
769 #[test]
770 fn insert_3_elements_try_re_get() {
771 let d1 = Doc::with_client_id(1);
772 let d2 = Doc::with_client_id(2);
773 let a1 = d1.get_or_insert_array("array");
774 {
775 let mut t1 = d1.transact_mut();
776
777 a1.push_back(&mut t1, 1);
778 a1.push_back(&mut t1, true);
779 a1.push_back(&mut t1, false);
780 let actual: Vec<_> = a1.iter(&t1).collect();
781 assert_eq!(
782 actual,
783 vec![Out::from(1.0), Out::from(true), Out::from(false)]
784 );
785 }
786
787 exchange_updates(&[&d1, &d2]);
788
789 let a2 = d2.get_or_insert_array("array");
790 let t2 = d2.transact();
791 let actual: Vec<_> = a2.iter(&t2).collect();
792 assert_eq!(
793 actual,
794 vec![Out::from(1.0), Out::from(true), Out::from(false)]
795 );
796 }
797
798 #[test]
799 fn concurrent_insert_with_3_conflicts() {
800 let d1 = Doc::with_client_id(1);
801 let a = d1.get_or_insert_array("array");
802 {
803 let mut txn = d1.transact_mut();
804 a.insert(&mut txn, 0, 0);
805 }
806
807 let d2 = Doc::with_client_id(2);
808 {
809 let mut txn = d1.transact_mut();
810 a.insert(&mut txn, 0, 1);
811 }
812
813 let d3 = Doc::with_client_id(3);
814 {
815 let mut txn = d1.transact_mut();
816 a.insert(&mut txn, 0, 2);
817 }
818
819 exchange_updates(&[&d1, &d2, &d3]);
820
821 let a1 = to_array(&d1);
822 let a2 = to_array(&d2);
823 let a3 = to_array(&d3);
824
825 assert_eq!(a1, a2, "Peer 1 and peer 2 states are different");
826 assert_eq!(a2, a3, "Peer 2 and peer 3 states are different");
827 }
828
829 fn to_array(d: &Doc) -> Vec<Out> {
830 let a = d.get_or_insert_array("array");
831 a.iter(&d.transact()).collect()
832 }
833
834 #[test]
835 fn concurrent_insert_remove_with_3_conflicts() {
836 let d1 = Doc::with_client_id(1);
837 {
838 let a = d1.get_or_insert_array("array");
839 let mut txn = d1.transact_mut();
840 a.insert_range(&mut txn, 0, ["x", "y", "z"]);
841 }
842 let d2 = Doc::with_client_id(2);
843 let d3 = Doc::with_client_id(3);
844
845 exchange_updates(&[&d1, &d2, &d3]);
846
847 {
848 let a1 = d1.get_or_insert_array("array");
850 let a2 = d2.get_or_insert_array("array");
851 let a3 = d3.get_or_insert_array("array");
852 let mut t1 = d1.transact_mut();
853 let mut t2 = d2.transact_mut();
854 let mut t3 = d3.transact_mut();
855
856 a1.insert(&mut t1, 1, 0); a2.remove_range(&mut t2, 0, 1); a2.remove_range(&mut t2, 1, 1); a3.insert(&mut t3, 1, 2); }
861
862 exchange_updates(&[&d1, &d2, &d3]);
863 let a1 = to_array(&d1);
866 let a2 = to_array(&d2);
867 let a3 = to_array(&d3);
868
869 assert_eq!(a1, a2, "Peer 1 and peer 2 states are different");
870 assert_eq!(a2, a3, "Peer 2 and peer 3 states are different");
871 }
872
873 #[test]
874 fn insertions_in_late_sync() {
875 let d1 = Doc::with_client_id(1);
876 {
877 let a = d1.get_or_insert_array("array");
878 let mut txn = d1.transact_mut();
879 a.push_back(&mut txn, "x");
880 a.push_back(&mut txn, "y");
881 }
882 let d2 = Doc::with_client_id(2);
883 let d3 = Doc::with_client_id(3);
884
885 exchange_updates(&[&d1, &d2, &d3]);
886
887 {
888 let a1 = d1.get_or_insert_array("array");
889 let a2 = d2.get_or_insert_array("array");
890 let a3 = d3.get_or_insert_array("array");
891 let mut t1 = d1.transact_mut();
892 let mut t2 = d2.transact_mut();
893 let mut t3 = d3.transact_mut();
894
895 a1.insert(&mut t1, 1, "user0");
896 a2.insert(&mut t2, 1, "user1");
897 a3.insert(&mut t3, 1, "user2");
898 }
899
900 exchange_updates(&[&d1, &d2, &d3]);
901
902 let a1 = to_array(&d1);
903 let a2 = to_array(&d2);
904 let a3 = to_array(&d3);
905
906 assert_eq!(a1, a2, "Peer 1 and peer 2 states are different");
907 assert_eq!(a2, a3, "Peer 2 and peer 3 states are different");
908 }
909
910 #[test]
911 fn removals_in_late_sync() {
912 let d1 = Doc::with_client_id(1);
913 {
914 let a = d1.get_or_insert_array("array");
915 let mut txn = d1.transact_mut();
916 a.push_back(&mut txn, "x");
917 a.push_back(&mut txn, "y");
918 }
919 let d2 = Doc::with_client_id(2);
920
921 exchange_updates(&[&d1, &d2]);
922
923 {
924 let a1 = d1.get_or_insert_array("array");
925 let a2 = d2.get_or_insert_array("array");
926 let mut t1 = d1.transact_mut();
927 let mut t2 = d2.transact_mut();
928
929 a2.remove_range(&mut t2, 1, 1);
930 a1.remove_range(&mut t1, 0, 2);
931 }
932
933 exchange_updates(&[&d1, &d2]);
934
935 let a1 = to_array(&d1);
936 let a2 = to_array(&d2);
937
938 assert_eq!(a1, a2, "Peer 1 and peer 2 states are different");
939 }
940
941 #[test]
942 fn insert_then_merge_delete_on_sync() {
943 let d1 = Doc::with_client_id(1);
944 {
945 let a = d1.get_or_insert_array("array");
946 let mut txn = d1.transact_mut();
947 a.push_back(&mut txn, "x");
948 a.push_back(&mut txn, "y");
949 a.push_back(&mut txn, "z");
950 }
951 let d2 = Doc::with_client_id(2);
952
953 exchange_updates(&[&d1, &d2]);
954
955 {
956 let a2 = d2.get_or_insert_array("array");
957 let mut t2 = d2.transact_mut();
958
959 a2.remove_range(&mut t2, 0, 3);
960 }
961
962 exchange_updates(&[&d1, &d2]);
963
964 let a1 = to_array(&d1);
965 let a2 = to_array(&d2);
966
967 assert_eq!(a1, a2, "Peer 1 and peer 2 states are different");
968 }
969
970 #[test]
971 fn iter_array_containing_types() {
972 let d = Doc::with_client_id(1);
973 let a = d.get_or_insert_array("arr");
974 let mut txn = d.transact_mut();
975 for i in 0..10 {
976 let mut m = HashMap::new();
977 m.insert("value".to_owned(), i);
978 a.push_back(&mut txn, MapPrelim::from_iter(m));
979 }
980
981 for (i, value) in a.iter(&txn).enumerate() {
982 match value {
983 Out::YMap(_) => {
984 assert_eq!(value.to_json(&txn), any!({"value": (i as f64) }))
985 }
986 _ => panic!("Value of array at index {} was no YMap", i),
987 }
988 }
989 }
990
991 #[test]
992 fn insert_and_remove_events() {
993 let d = Doc::with_client_id(1);
994 let array = d.get_or_insert_array("array");
995 let happened = Arc::new(AtomicBool::new(false));
996 let happened_clone = happened.clone();
997 let _sub = array.observe(move |_, _| {
998 happened_clone.store(true, Ordering::Relaxed);
999 });
1000
1001 {
1002 let mut txn = d.transact_mut();
1003 array.insert_range(&mut txn, 0, [0, 1, 2]);
1004 }
1006 assert!(
1007 happened.swap(false, Ordering::Relaxed),
1008 "insert of [0,1,2] should trigger event"
1009 );
1010
1011 {
1012 let mut txn = d.transact_mut();
1013 array.remove_range(&mut txn, 0, 1);
1014 }
1016 assert!(
1017 happened.swap(false, Ordering::Relaxed),
1018 "removal of [0] should trigger event"
1019 );
1020
1021 {
1022 let mut txn = d.transact_mut();
1023 array.remove_range(&mut txn, 0, 2);
1024 }
1026 assert!(
1027 happened.swap(false, Ordering::Relaxed),
1028 "removal of [1,2] should trigger event"
1029 );
1030 }
1031
1032 #[test]
1033 fn insert_and_remove_event_changes() {
1034 let d1 = Doc::with_client_id(1);
1035 let array = d1.get_or_insert_array("array");
1036 let added = Arc::new(ArcSwapOption::default());
1037 let removed = Arc::new(ArcSwapOption::default());
1038 let delta = Arc::new(ArcSwapOption::default());
1039
1040 let (added_c, removed_c, delta_c) = (added.clone(), removed.clone(), delta.clone());
1041 let _sub = array.observe(move |txn, e| {
1042 added_c.store(Some(Arc::new(e.inserts(txn).clone())));
1043 removed_c.store(Some(Arc::new(e.removes(txn).clone())));
1044 delta_c.store(Some(Arc::new(e.delta(txn).to_vec())));
1045 });
1046
1047 {
1048 let mut txn = d1.transact_mut();
1049 array.push_back(&mut txn, 4);
1050 array.push_back(&mut txn, "dtrn");
1051 }
1053 assert_eq!(
1054 added.swap(None),
1055 Some(
1056 HashSet::from([ID::new(ClientID::new(1), 0), ID::new(ClientID::new(1), 1)]).into()
1057 )
1058 );
1059 assert_eq!(removed.swap(None), Some(HashSet::new().into()));
1060 assert_eq!(
1061 delta.swap(None),
1062 Some(
1063 vec![Change::Added(vec![
1064 Any::Number(4.0).into(),
1065 Any::String("dtrn".into()).into()
1066 ])]
1067 .into()
1068 )
1069 );
1070
1071 {
1072 let mut txn = d1.transact_mut();
1073 array.remove_range(&mut txn, 0, 1);
1074 }
1075 assert_eq!(added.swap(None), Some(HashSet::new().into()));
1076 assert_eq!(
1077 removed.swap(None),
1078 Some(HashSet::from([ID::new(ClientID::new(1), 0)]).into())
1079 );
1080 assert_eq!(delta.swap(None), Some(vec![Change::Removed(1)].into()));
1081
1082 {
1083 let mut txn = d1.transact_mut();
1084 array.insert(&mut txn, 1, 0.5);
1085 }
1086 assert_eq!(
1087 added.swap(None),
1088 Some(HashSet::from([ID::new(ClientID::new(1), 2)]).into())
1089 );
1090 assert_eq!(removed.swap(None), Some(HashSet::new().into()));
1091 assert_eq!(
1092 delta.swap(None),
1093 Some(
1094 vec![
1095 Change::Retain(1),
1096 Change::Added(vec![Any::Number(0.5).into()])
1097 ]
1098 .into()
1099 )
1100 );
1101
1102 let d2 = Doc::with_client_id(2);
1103 let array2 = d2.get_or_insert_array("array");
1104 let (added_c, removed_c, delta_c) = (added.clone(), removed.clone(), delta.clone());
1105 let _sub = array2.observe(move |txn, e| {
1106 added_c.store(Some(e.inserts(txn).clone().into()));
1107 removed_c.store(Some(e.removes(txn).clone().into()));
1108 delta_c.store(Some(e.delta(txn).to_vec().into()));
1109 });
1110
1111 {
1112 let t1 = d1.transact_mut();
1113 let mut t2 = d2.transact_mut();
1114
1115 let sv = t2.state_vector();
1116 let mut encoder = EncoderV1::new();
1117 t1.encode_diff(&sv, &mut encoder);
1118 t2.apply_update(Update::decode_v1(encoder.to_vec().as_slice()).unwrap())
1119 .unwrap();
1120 }
1121
1122 assert_eq!(
1123 added.swap(None),
1124 Some(HashSet::from([ID::new(ClientID::new(1), 1)]).into())
1125 );
1126 assert_eq!(removed.swap(None), Some(HashSet::new().into()));
1127 assert_eq!(
1128 delta.swap(None),
1129 Some(
1130 vec![Change::Added(vec![
1131 Any::String("dtrn".into()).into(),
1132 Any::Number(0.5).into(),
1133 ])]
1134 .into()
1135 )
1136 );
1137 }
1138
1139 #[test]
1140 fn target_on_local_and_remote() {
1141 let d1 = Doc::with_client_id(1);
1142 let d2 = Doc::with_client_id(2);
1143 let a1 = d1.get_or_insert_array("array");
1144 let a2 = d2.get_or_insert_array("array");
1145
1146 let c1 = Arc::new(ArcSwapOption::default());
1147 let c1c = c1.clone();
1148 let _s1 = a1.observe(move |_, e| {
1149 c1c.store(Some(e.target().hook().into()));
1150 });
1151 let c2 = Arc::new(ArcSwapOption::default());
1152 let c2c = c2.clone();
1153 let _s2 = a2.observe(move |_, e| {
1154 c2c.store(Some(e.target().hook().into()));
1155 });
1156
1157 {
1158 let mut t1 = d1.transact_mut();
1159 a1.insert_range(&mut t1, 0, [1, 2]);
1160 }
1161 exchange_updates(&[&d1, &d2]);
1162
1163 assert_eq!(c1.swap(None), Some(Arc::new(a1.hook())));
1164 assert_eq!(c2.swap(None), Some(Arc::new(a2.hook())));
1165 }
1166
1167 use crate::transaction::ReadTxn;
1168 use crate::updates::decoder::Decode;
1169 use crate::updates::encoder::{Encoder, EncoderV1};
1170 use arc_swap::ArcSwapOption;
1171 use fastrand::Rng;
1172 use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
1173 use std::time::Duration;
1174
1175 static UNIQUE_NUMBER: AtomicI64 = AtomicI64::new(0);
1176
1177 fn get_unique_number() -> i64 {
1178 UNIQUE_NUMBER.fetch_add(1, Ordering::SeqCst)
1179 }
1180
1181 fn array_transactions() -> [Box<dyn Fn(&mut Doc, &mut Rng)>; 5] {
1182 fn move_one(doc: &mut Doc, rng: &mut Rng) {
1183 let yarray = doc.get_or_insert_array("array");
1184 let mut txn = doc.transact_mut();
1185 if yarray.len(&txn) != 0 {
1186 let pos = rng.between(0, yarray.len(&txn) - 1);
1187 let len = 1;
1188 let new_pos_adjusted = rng.between(0, yarray.len(&txn) - 1);
1189 let new_pos = new_pos_adjusted + if new_pos_adjusted > pos { len } else { 0 };
1190 if let Any::Array(expected) = yarray.to_json(&txn) {
1191 let mut expected = Vec::from(expected.as_ref());
1192 let moved = expected.remove(pos as usize);
1193 let insert_pos = if pos < new_pos {
1194 new_pos - len
1195 } else {
1196 new_pos
1197 } as usize;
1198 expected.insert(insert_pos, moved);
1199
1200 yarray.move_to(&mut txn, pos, new_pos);
1201
1202 let actual = yarray.to_json(&txn);
1203 assert_eq!(actual, Any::from(expected))
1204 } else {
1205 panic!("should not happen")
1206 }
1207 }
1208 }
1209 fn insert(doc: &mut Doc, rng: &mut Rng) {
1210 let yarray = doc.get_or_insert_array("array");
1211 let mut txn = doc.transact_mut();
1212 let unique_number = get_unique_number();
1213 let len = rng.between(1, 4);
1214 let content: Vec<_> = (0..len)
1215 .into_iter()
1216 .map(|_| Any::BigInt(unique_number))
1217 .collect();
1218 let mut pos = rng.between(0, yarray.len(&txn)) as usize;
1219 if let Any::Array(expected) = yarray.to_json(&txn) {
1220 let mut expected = Vec::from(expected.as_ref());
1221 yarray.insert_range(&mut txn, pos as u32, content.clone());
1222
1223 for any in content {
1224 expected.insert(pos, any);
1225 pos += 1;
1226 }
1227 let actual = yarray.to_json(&txn);
1228 assert_eq!(actual, Any::from(expected))
1229 } else {
1230 panic!("should not happen")
1231 }
1232 }
1233
1234 fn insert_type_array(doc: &mut Doc, rng: &mut Rng) {
1235 let yarray = doc.get_or_insert_array("array");
1236 let mut txn = doc.transact_mut();
1237 let pos = rng.between(0, yarray.len(&txn));
1238 let array2 = yarray.insert(&mut txn, pos, ArrayPrelim::from([1, 2, 3, 4]));
1239 let expected: Arc<[Any]> = (1..=4).map(|i| Any::Number(i as f64)).collect();
1240 assert_eq!(array2.to_json(&txn), Any::Array(expected));
1241 }
1242
1243 fn insert_type_map(doc: &mut Doc, rng: &mut Rng) {
1244 let yarray = doc.get_or_insert_array("array");
1245 let mut txn = doc.transact_mut();
1246 let pos = rng.between(0, yarray.len(&txn));
1247 let map = yarray.insert(&mut txn, pos, MapPrelim::default());
1248 map.insert(&mut txn, "someprop".to_string(), 42);
1249 map.insert(&mut txn, "someprop".to_string(), 43);
1250 map.insert(&mut txn, "someprop".to_string(), 44);
1251 }
1252
1253 fn delete(doc: &mut Doc, rng: &mut Rng) {
1254 let yarray = doc.get_or_insert_array("array");
1255 let mut txn = doc.transact_mut();
1256 let len = yarray.len(&txn);
1257 if len > 0 {
1258 let pos = rng.between(0, len - 1);
1259 let del_len = rng.between(1, 2.min(len - pos));
1260 if rng.bool() {
1261 if let Out::YArray(array2) = yarray.get(&txn, pos).unwrap() {
1262 let pos = rng.between(0, array2.len(&txn) - 1);
1263 let del_len = rng.between(0, 2.min(array2.len(&txn) - pos));
1264 array2.remove_range(&mut txn, pos, del_len);
1265 }
1266 } else {
1267 if let Any::Array(old_content) = yarray.to_json(&txn) {
1268 let mut old_content = Vec::from(old_content.as_ref());
1269 yarray.remove_range(&mut txn, pos, del_len);
1270 old_content.drain(pos as usize..(pos + del_len) as usize);
1271 assert_eq!(yarray.to_json(&txn), Any::from(old_content));
1272 } else {
1273 panic!("should not happen")
1274 }
1275 }
1276 }
1277 }
1278
1279 [
1280 Box::new(insert),
1281 Box::new(insert_type_array),
1282 Box::new(insert_type_map),
1283 Box::new(delete),
1284 Box::new(move_one),
1285 ]
1286 }
1287
1288 fn fuzzy(iterations: usize) {
1289 run_scenario(0, &array_transactions(), 5, iterations)
1290 }
1291
1292 #[test]
1293 fn fuzzy_test_6() {
1294 fuzzy(6)
1295 }
1296
1297 #[test]
1298 fn fuzzy_test_300() {
1299 fuzzy(300)
1300 }
1301
1302 #[test]
1303 fn get_at_removed_index() {
1304 let d1 = Doc::with_client_id(1);
1305 let a1 = d1.get_or_insert_array("array");
1306 let mut t1 = d1.transact_mut();
1307
1308 a1.insert_range(&mut t1, 0, ["A"]);
1309 a1.remove(&mut t1, 0);
1310
1311 let actual = a1.get(&t1, 0);
1312 assert_eq!(actual, None);
1313 }
1314
1315 #[test]
1316 fn observe_deep_event_order() {
1317 let doc = Doc::with_client_id(1);
1318 let array = doc.get_or_insert_array("array");
1319
1320 let paths = Arc::new(Mutex::new(vec![]));
1321 let paths_copy = paths.clone();
1322
1323 let _sub = array.observe_deep(move |_txn, e| {
1324 let path: Vec<Path> = e.iter().map(Event::path).collect();
1325 paths_copy.lock().unwrap().push(path);
1326 });
1327
1328 array.insert(&mut doc.transact_mut(), 0, MapPrelim::default());
1329
1330 {
1331 let mut txn = doc.transact_mut();
1332 let map = array.get(&txn, 0).unwrap().cast::<MapRef>().unwrap();
1333 map.insert(&mut txn, "a", "a");
1334 array.insert(&mut txn, 0, 0);
1335 }
1336
1337 let expected = &[
1338 vec![Path::default()],
1339 vec![Path::default(), Path::from([PathSegment::Index(1)])],
1340 ];
1341 let actual = paths.lock().unwrap();
1342 assert_eq!(actual.as_slice(), expected);
1343 }
1344
1345 #[test]
1346 fn move_1() {
1347 let d1 = Doc::with_client_id(1);
1348 let a1 = d1.get_or_insert_array("array");
1349
1350 let d2 = Doc::with_client_id(2);
1351 let a2 = d2.get_or_insert_array("array");
1352
1353 let e1 = Arc::new(ArcSwapOption::default());
1354 let inner = e1.clone();
1355 let _s1 = a1.observe(move |txn, e| {
1356 inner.store(Some(Arc::new(e.delta(txn).to_vec())));
1357 });
1358
1359 let e2 = Arc::new(ArcSwapOption::default());
1360 let inner = e2.clone();
1361 let _s2 = a2.observe(move |txn, e| {
1362 inner.store(Some(Arc::new(e.delta(txn).to_vec())));
1363 });
1364
1365 {
1366 let mut txn = d1.transact_mut();
1367 a1.insert_range(&mut txn, 0, [1, 2, 3]);
1368 a1.move_to(&mut txn, 1, 0);
1369 }
1370 assert_eq!(a1.to_json(&d1.transact()), vec![2, 1, 3].into());
1371
1372 exchange_updates(&[&d1, &d2]);
1373
1374 assert_eq!(a2.to_json(&d2.transact()), vec![2, 1, 3].into());
1375 let actual = e2.load_full();
1376 assert_eq!(
1377 actual,
1378 Some(Arc::new(vec![Change::Added(vec![
1379 2.into(),
1380 1.into(),
1381 3.into()
1382 ])]))
1383 );
1384
1385 a1.move_to(&mut d1.transact_mut(), 0, 2);
1386
1387 assert_eq!(a1.to_json(&d1.transact()), vec![1, 2, 3].into());
1388 let actual = e1.load_full();
1389 assert_eq!(
1390 actual,
1391 Some(Arc::new(vec![
1392 Change::Removed(1),
1393 Change::Retain(1),
1394 Change::Added(vec![2.into()])
1395 ]))
1396 )
1397 }
1398
1399 #[test]
1400 fn move_2() {
1401 let d1 = Doc::with_client_id(1);
1402 let a1 = d1.get_or_insert_array("array");
1403
1404 let d2 = Doc::with_client_id(2);
1405 let a2 = d2.get_or_insert_array("array");
1406
1407 let e1 = Arc::new(ArcSwapOption::default());
1408 let inner = e1.clone();
1409 let _s1 = a1.observe(move |txn, e| {
1410 inner.store(Some(Arc::new(e.delta(txn).to_vec())));
1411 });
1412
1413 let e2 = Arc::new(ArcSwapOption::default());
1414 let inner = e2.clone();
1415 let _s2 = a2.observe(move |txn, e| {
1416 inner.store(Some(Arc::new(e.delta(txn).to_vec())));
1417 });
1418
1419 a1.insert_range(&mut d1.transact_mut(), 0, [1, 2]);
1420 a1.move_to(&mut d1.transact_mut(), 1, 0);
1421 assert_eq!(a1.to_json(&d1.transact()), vec![2, 1].into());
1422 {
1423 let actual = e1.load_full();
1424 assert_eq!(
1425 actual,
1426 Some(Arc::new(vec![
1427 Change::Added(vec![2.into()]),
1428 Change::Retain(1),
1429 Change::Removed(1)
1430 ]))
1431 );
1432 }
1433
1434 exchange_updates(&[&d1, &d2]);
1435
1436 assert_eq!(a2.to_json(&d2.transact()), vec![2, 1].into());
1437 {
1438 let actual = e2.load_full();
1439 assert_eq!(
1440 actual,
1441 Some(Arc::new(vec![Change::Added(vec![2.into(), 1.into()])]))
1442 );
1443 }
1444
1445 a1.move_to(&mut d1.transact_mut(), 0, 2);
1446 assert_eq!(a1.to_json(&d1.transact()), vec![1, 2].into());
1447 {
1448 let actual = e1.load_full();
1449 assert_eq!(
1450 actual,
1451 Some(Arc::new(vec![
1452 Change::Removed(1),
1453 Change::Retain(1),
1454 Change::Added(vec![2.into()])
1455 ]))
1456 );
1457 }
1458 }
1459
1460 #[test]
1461 fn move_cycles() {
1462 let d1 = Doc::with_client_id(1);
1463 let a1 = d1.get_or_insert_array("array");
1464
1465 let d2 = Doc::with_client_id(2);
1466 let a2 = d2.get_or_insert_array("array");
1467
1468 a1.insert_range(&mut d1.transact_mut(), 0, [1, 2, 3, 4]);
1469 exchange_updates(&[&d1, &d2]);
1470
1471 a1.move_range_to(&mut d1.transact_mut(), 0, Assoc::After, 1, Assoc::Before, 3);
1472 assert_eq!(a1.to_json(&d1.transact()), vec![3, 1, 2, 4].into());
1473
1474 a2.move_range_to(&mut d2.transact_mut(), 2, Assoc::After, 3, Assoc::Before, 1);
1475 assert_eq!(a2.to_json(&d2.transact()), vec![1, 3, 4, 2].into());
1476
1477 exchange_updates(&[&d1, &d2]);
1478 exchange_updates(&[&d1, &d2]); assert_eq!(a1.len(&d1.transact()), 4);
1481 assert_eq!(a1.to_json(&d1.transact()), a2.to_json(&d2.transact()));
1482 }
1483
1484 #[test]
1485 #[ignore] fn move_range_to() {
1487 let doc = Doc::with_client_id(1);
1488 let arr = doc.get_or_insert_array("array");
1489 {
1491 let mut txn = doc.transact_mut();
1492 let arr_len = arr.len(&txn);
1493 arr.remove_range(&mut txn, 0, arr_len);
1494 let arr_len = arr.len(&txn);
1495 assert_eq!(arr_len, 0);
1496 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3]);
1497 }
1498 arr.move_range_to(
1499 &mut doc.transact_mut(),
1500 1,
1501 Assoc::After,
1502 2,
1503 Assoc::Before,
1504 4,
1505 );
1506 assert_eq!(arr.to_json(&doc.transact()), vec![0, 3, 1, 2].into());
1507
1508 {
1510 let mut txn = doc.transact_mut();
1511 let arr_len = arr.len(&txn);
1512 arr.remove_range(&mut txn, 0, arr_len);
1513 let arr_len = arr.len(&txn);
1514 assert_eq!(arr_len, 0);
1515 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1516 }
1517 arr.move_range_to(
1518 &mut doc.transact_mut(),
1519 0,
1520 Assoc::After,
1521 0,
1522 Assoc::Before,
1523 10,
1524 );
1525 assert_eq!(
1526 arr.to_json(&doc.transact()),
1527 vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0].into()
1528 );
1529
1530 {
1532 let mut txn = doc.transact_mut();
1533 let arr_len = arr.len(&txn);
1534 arr.remove_range(&mut txn, 0, arr_len);
1535 let arr_len = arr.len(&txn);
1536 assert_eq!(arr_len, 0);
1537 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1538 }
1539 arr.move_range_to(
1540 &mut doc.transact_mut(),
1541 0,
1542 Assoc::After,
1543 1,
1544 Assoc::Before,
1545 10,
1546 );
1547 assert_eq!(
1548 arr.to_json(&doc.transact()),
1549 vec![2, 3, 4, 5, 6, 7, 8, 9, 0, 1].into()
1550 );
1551
1552 {
1554 let mut txn = doc.transact_mut();
1555 let arr_len = arr.len(&txn);
1556 arr.remove_range(&mut txn, 0, arr_len);
1557 let arr_len = arr.len(&txn);
1558 assert_eq!(arr_len, 0);
1559 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1560 }
1561 arr.move_range_to(
1562 &mut doc.transact_mut(),
1563 3,
1564 Assoc::After,
1565 5,
1566 Assoc::Before,
1567 7,
1568 );
1569 assert_eq!(
1570 arr.to_json(&doc.transact()),
1571 vec![0, 1, 2, 6, 3, 4, 5, 7, 8, 9].into()
1572 );
1573
1574 {
1576 let mut txn = doc.transact_mut();
1577 let arr_len = arr.len(&txn);
1578 arr.remove_range(&mut txn, 0, arr_len);
1579 let arr_len = arr.len(&txn);
1580 assert_eq!(arr_len, 0);
1581 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1582 }
1583 arr.move_range_to(
1584 &mut doc.transact_mut(),
1585 1,
1586 Assoc::After,
1587 0,
1588 Assoc::Before,
1589 10,
1590 );
1591 assert_eq!(
1592 arr.to_json(&doc.transact()),
1593 vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into()
1594 );
1595
1596 {
1598 let mut txn = doc.transact_mut();
1599 let arr_len = arr.len(&txn);
1600 arr.remove_range(&mut txn, 0, arr_len);
1601 let arr_len = arr.len(&txn);
1602 assert_eq!(arr_len, 0);
1603 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1604 }
1605 arr.move_range_to(
1606 &mut doc.transact_mut(),
1607 3,
1608 Assoc::After,
1609 5,
1610 Assoc::Before,
1611 5,
1612 );
1613 assert_eq!(
1614 arr.to_json(&doc.transact()),
1615 vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into()
1616 );
1617
1618 {
1620 let mut txn = doc.transact_mut();
1621 let arr_len = arr.len(&txn);
1622 arr.remove_range(&mut txn, 0, arr_len);
1623 let arr_len = arr.len(&txn);
1624 assert_eq!(arr_len, 0);
1625 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1626 }
1627 arr.move_range_to(
1628 &mut doc.transact_mut(),
1629 9,
1630 Assoc::After,
1631 9,
1632 Assoc::Before,
1633 0,
1634 );
1635 assert_eq!(
1636 arr.to_json(&doc.transact()),
1637 vec![9, 0, 1, 2, 3, 4, 5, 6, 7, 8].into()
1638 );
1639
1640 {
1642 let mut txn = doc.transact_mut();
1643 let arr_len = arr.len(&txn);
1644 arr.remove_range(&mut txn, 0, arr_len);
1645 let arr_len = arr.len(&txn);
1646 assert_eq!(arr_len, 0);
1647 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1648 }
1649 arr.move_range_to(
1650 &mut doc.transact_mut(),
1651 8,
1652 Assoc::After,
1653 9,
1654 Assoc::Before,
1655 0,
1656 );
1657 assert_eq!(
1658 arr.to_json(&doc.transact()),
1659 vec![8, 9, 0, 1, 2, 3, 4, 5, 6, 7].into()
1660 );
1661
1662 {
1664 let mut txn = doc.transact_mut();
1665 let arr_len = arr.len(&txn);
1666 arr.remove_range(&mut txn, 0, arr_len);
1667 let arr_len = arr.len(&txn);
1668 assert_eq!(arr_len, 0);
1669 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1670 }
1671 arr.move_range_to(
1672 &mut doc.transact_mut(),
1673 4,
1674 Assoc::After,
1675 6,
1676 Assoc::Before,
1677 3,
1678 );
1679 assert_eq!(
1680 arr.to_json(&doc.transact()),
1681 vec![0, 1, 2, 4, 5, 6, 3, 7, 8, 9].into()
1682 );
1683
1684 {
1686 let mut txn = doc.transact_mut();
1687 let arr_len = arr.len(&txn);
1688 arr.remove_range(&mut txn, 0, arr_len);
1689 let arr_len = arr.len(&txn);
1690 assert_eq!(arr_len, 0);
1691 arr.insert_range(&mut txn, arr_len, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1692 }
1693 arr.move_range_to(
1694 &mut doc.transact_mut(),
1695 3,
1696 Assoc::After,
1697 5,
1698 Assoc::Before,
1699 3,
1700 );
1701 assert_eq!(
1702 arr.to_json(&doc.transact()),
1703 vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into()
1704 );
1705 }
1706
1707 #[test]
1708 fn multi_threading() {
1709 use std::sync::{Arc, RwLock};
1710 use std::thread::{sleep, spawn};
1711
1712 let doc = Arc::new(RwLock::new(Doc::with_client_id(1)));
1713
1714 let d2 = doc.clone();
1715 let h2 = spawn(move || {
1716 for _ in 0..10 {
1717 let millis = fastrand::u64(1..20);
1718 sleep(Duration::from_millis(millis));
1719
1720 let doc = d2.write().unwrap();
1721 let array = doc.get_or_insert_array("test");
1722 let mut txn = doc.transact_mut();
1723 array.push_back(&mut txn, "a");
1724 }
1725 });
1726
1727 let d3 = doc.clone();
1728 let h3 = spawn(move || {
1729 for _ in 0..10 {
1730 let millis = fastrand::u64(1..20);
1731 sleep(Duration::from_millis(millis));
1732
1733 let doc = d3.write().unwrap();
1734 let array = doc.get_or_insert_array("test");
1735 let mut txn = doc.transact_mut();
1736 array.push_back(&mut txn, "b");
1737 }
1738 });
1739
1740 h3.join().unwrap();
1741 h2.join().unwrap();
1742
1743 let doc = doc.read().unwrap();
1744 let array = doc.get_or_insert_array("test");
1745 let len = array.len(&doc.transact());
1746 assert_eq!(len, 20);
1747 }
1748
1749 #[test]
1750 fn move_last_elem_iter() {
1751 let doc = Doc::with_client_id(1);
1754 let array = doc.get_or_insert_array("array");
1755 let mut txn = doc.transact_mut();
1756 array.insert_range(&mut txn, 0, [1, 2, 3]);
1757 drop(txn);
1758
1759 let mut txn = doc.transact_mut();
1760 array.move_to(&mut txn, 2, 0);
1761
1762 let mut iter = array.iter(&txn);
1763 let v = iter.next();
1764 assert_eq!(v, Some(3.into()));
1765 let v = iter.next();
1766 assert_eq!(v, Some(1.into()));
1767 let v = iter.next();
1768 assert_eq!(v, Some(2.into()));
1769 let v = iter.next();
1770 assert_eq!(v, None);
1771 }
1772
1773 #[test]
1774 fn insert_empty_range() {
1775 let doc = Doc::with_client_id(1);
1776 let mut txn = doc.transact_mut();
1777 let array = txn.get_or_insert_array("array");
1778
1779 array.insert(&mut txn, 0, 1);
1780 array.insert_range::<_, Any>(&mut txn, 1, []);
1781 array.push_back(&mut txn, 2);
1782
1783 assert_eq!(
1784 array.iter(&txn).collect::<Vec<_>>(),
1785 vec![1.into(), 2.into()]
1786 );
1787
1788 let data = txn.encode_state_as_update_v1(&StateVector::default());
1789
1790 let doc2 = Doc::with_client_id(2);
1791 let mut txn = doc2.transact_mut();
1792 let array = txn.get_or_insert_array("array");
1793 txn.apply_update(Update::decode_v1(&data).unwrap()).unwrap();
1794
1795 assert_eq!(
1796 array.iter(&txn).collect::<Vec<_>>(),
1797 vec![1.into(), 2.into()]
1798 );
1799 }
1800}