1use std::cell::UnsafeCell;
4use std::collections::vec_deque::Drain;
5use std::collections::{TryReserveError, VecDeque};
6use std::fmt::Debug;
7use std::marker::PhantomData;
8use std::ops::{Bound, Deref, DerefMut, Index, IndexMut, RangeBounds};
9
10use serde::Serialize;
11
12use crate::helper::macros::{default_impl_ref_observe, delegate_methods};
13use crate::helper::{AsDeref, AsDerefMut, ObserverState, Pointer, QuasiObserver, Succ, Unsigned, Zero};
14use crate::observe::{DefaultSpec, Observer, SerializeObserver};
15use crate::{MutationKind, Mutations, Observe, PathSegment};
16
17struct VecDequeObserverState<O> {
24 back_truncate_len: usize,
26 back_append_index: usize,
30 front_mutated: bool,
32 inner: UnsafeCell<VecDeque<O>>,
37}
38
39impl<O> VecDequeObserverState<O> {
40 fn mark_back_truncate(&mut self, new_len: usize) {
41 self.back_truncate_len += self.back_append_index - new_len;
42 self.back_append_index = new_len;
43 }
44
45 fn mark_replace(&mut self) {
48 self.inner.get_mut().clear();
49 self.back_truncate_len += self.back_append_index;
50 self.back_append_index = 0;
51 }
52}
53
54impl<O> ObserverState for VecDequeObserverState<O>
55where
56 O: Observer<InnerDepth = Zero, Head: Sized>,
57{
58 type Target = VecDeque<O::Head>;
59
60 fn invalidate(this: &mut Self, _: &VecDeque<O::Head>) {
61 this.mark_replace();
62 }
63}
64
65pub struct VecDequeObserver<'ob, O, S: ?Sized, D = Zero> {
75 ptr: Pointer<S>,
76 state: VecDequeObserverState<O>,
77 phantom: PhantomData<&'ob mut D>,
78}
79
80impl<'ob, O, S: ?Sized, D> Deref for VecDequeObserver<'ob, O, S, D> {
81 type Target = Pointer<S>;
82
83 fn deref(&self) -> &Self::Target {
84 &self.ptr
85 }
86}
87
88impl<'ob, O, S: ?Sized, D> DerefMut for VecDequeObserver<'ob, O, S, D> {
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 std::ptr::from_mut(self).expose_provenance();
91 Pointer::invalidate(&mut self.ptr);
92 &mut self.ptr
93 }
94}
95
96impl<'ob, O, S: ?Sized, D> QuasiObserver for VecDequeObserver<'ob, O, S, D>
97where
98 D: Unsigned,
99 O: Observer<InnerDepth = Zero, Head: Sized>,
100 S: AsDeref<D, Target = VecDeque<O::Head>>,
101{
102 type Head = S;
103 type OuterDepth = Succ<Zero>;
104 type InnerDepth = D;
105
106 fn invalidate(this: &mut Self) {
107 this.state.mark_replace();
108 }
109}
110
111impl<'ob, O, S: ?Sized, D> Observer for VecDequeObserver<'ob, O, S, D>
112where
113 D: Unsigned,
114 O: Observer<InnerDepth = Zero, Head: Sized>,
115 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
116{
117 fn observe(head: &mut Self::Head) -> Self {
118 let len = head.as_deref_mut().len();
119 Self {
120 state: VecDequeObserverState {
121 back_truncate_len: 0,
122 back_append_index: len,
123 front_mutated: false,
124 inner: UnsafeCell::new(VecDeque::new()),
125 },
126 ptr: Pointer::new(head),
127 phantom: PhantomData,
128 }
129 }
130
131 unsafe fn relocate(this: &mut Self, head: &mut Self::Head) {
132 Pointer::set(this, head);
133 }
134}
135
136impl<'ob, O, S: ?Sized, D> SerializeObserver for VecDequeObserver<'ob, O, S, D>
137where
138 D: Unsigned,
139 O: Observer<InnerDepth = Zero, Head: Sized> + SerializeObserver,
140 O::Head: Serialize + 'static,
141 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
142{
143 unsafe fn flush(this: &mut Self) -> Mutations {
144 let deque = (*this.ptr).as_deref_mut();
145 let len = deque.len();
146 let back_append_index = core::mem::replace(&mut this.state.back_append_index, len);
147 let back_truncate_len = core::mem::replace(&mut this.state.back_truncate_len, 0);
148 let front_mutated = core::mem::replace(&mut this.state.front_mutated, false);
149
150 let slice = deque.make_contiguous();
152
153 if front_mutated || (back_append_index == 0 && back_truncate_len > 0) {
155 if len > 0 || back_truncate_len > 0 {
156 this.state.inner.get_mut().clear();
158 return Mutations::replace(slice);
159 }
160 return Mutations::new();
161 }
162
163 let mut mutations = Mutations::new();
164 #[cfg(feature = "truncate")]
165 if back_truncate_len > 0 {
166 mutations.extend(MutationKind::Truncate(back_truncate_len));
167 }
168
169 unsafe { relocate(&this.state.inner, &mut slice[..back_append_index]) };
171
172 #[cfg(feature = "append")]
173 if len > back_append_index {
174 mutations.extend(Mutations::append(&slice[back_append_index..]));
175 }
176
177 let inner = this.state.inner.get_mut();
179 let existing_len = back_append_index.min(inner.len());
182 let existing = inner.make_contiguous();
183 let mut is_replace = true;
184 for (index, ob) in existing[..existing_len].iter_mut().enumerate().rev() {
185 let mutations_i = unsafe { SerializeObserver::flush(ob) };
186 is_replace &= mutations_i.is_replace();
187 mutations.insert(PathSegment::Negative(len - index), mutations_i);
188 }
189
190 inner.truncate(existing_len);
192
193 if is_replace && (back_append_index > 0 || back_truncate_len > 0) {
194 return Mutations::replace(slice);
195 }
196
197 mutations
198 }
199}
200
201unsafe fn relocate<O>(inner: &UnsafeCell<VecDeque<O>>, deque_slice: &mut [O::Head])
210where
211 O: Observer<InnerDepth = Zero, Head: Sized>,
212{
213 let observers = unsafe { &mut *inner.get() };
214 if observers.len() < deque_slice.len() {
215 for value in deque_slice[observers.len()..].iter_mut() {
216 observers.push_back(O::observe(value));
217 }
218 }
219 observers.truncate(deque_slice.len());
220 let ob_contiguous = observers.make_contiguous();
221 for (ob, value) in ob_contiguous.iter_mut().zip(deque_slice.iter_mut()) {
222 unsafe { Observer::relocate(ob, value) };
223 }
224}
225
226impl<'ob, O, S: ?Sized, D> VecDequeObserver<'ob, O, S, D>
227where
228 D: Unsigned,
229 O: Observer<InnerDepth = Zero, Head: Sized>,
230 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
231{
232 delegate_methods! { untracked_mut() as VecDeque =>
233 pub fn reserve_exact(&mut self, additional: usize);
234 pub fn reserve(&mut self, additional: usize);
235 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>;
236 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
237 pub fn shrink_to_fit(&mut self);
238 pub fn shrink_to(&mut self, min_capacity: usize);
239 }
240
241 pub fn make_contiguous(&mut self) -> &mut [O] {
246 let deque = (*self.ptr).as_deref_mut();
247 let deque_slice = deque.make_contiguous();
248 unsafe { relocate(&self.state.inner, deque_slice) };
249 self.state.inner.get_mut().make_contiguous()
250 }
251
252 #[expect(clippy::mut_from_ref)]
254 fn force_index(&self, index: usize) -> Option<&mut O> {
255 let deque = unsafe { Pointer::as_mut(&self.ptr).as_deref_mut() };
256 let len = deque.len();
257 if index >= len {
258 return None;
259 }
260 let slice = deque.make_contiguous();
262 unsafe { relocate(&self.state.inner, slice) };
263 let observers = unsafe { &mut *self.state.inner.get() };
264 observers.get_mut(index)
265 }
266
267 fn force_all(&mut self) -> &mut VecDeque<O> {
269 let deque = (*self.ptr).as_deref_mut();
270 let slice = deque.make_contiguous();
271 unsafe { relocate(&self.state.inner, slice) };
272 self.state.inner.get_mut()
273 }
274
275 pub fn get_mut(&mut self, index: usize) -> Option<&mut O> {
277 let deque = (*self.ptr).as_deref_mut();
278 let len = deque.len();
279 if index >= len {
280 return None;
281 }
282 let slice = deque.make_contiguous();
283 unsafe { relocate(&self.state.inner, slice) };
284 self.state.inner.get_mut().get_mut(index)
285 }
286
287 pub fn front_mut(&mut self) -> Option<&mut O> {
289 if (*self).untracked_ref().is_empty() {
290 return None;
291 }
292 self.get_mut(0)
293 }
294
295 pub fn back_mut(&mut self) -> Option<&mut O> {
297 let len = (*self).untracked_ref().len();
298 if len == 0 {
299 return None;
300 }
301 self.get_mut(len - 1)
302 }
303
304 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut O> {
308 let observers = self.force_all();
309 observers.iter_mut()
310 }
311
312 pub fn as_mut_slices(&mut self) -> (&mut [O], &mut [O]) {
317 self.force_all();
318 self.state.inner.get_mut().as_mut_slices()
319 }
320
321 pub fn range_mut<R>(&mut self, range: R) -> impl Iterator<Item = &mut O>
323 where
324 R: RangeBounds<usize> + Clone,
325 {
326 let deque = (*self.ptr).as_deref_mut();
327 let slice = deque.make_contiguous();
328 unsafe { relocate(&self.state.inner, slice) };
329 self.state.inner.get_mut().range_mut(range)
330 }
331
332 pub fn swap(&mut self, i: usize, j: usize) {
334 if i != j {
335 let observers = self.state.inner.get_mut();
337 if let Some(ob) = observers.get_mut(i) {
338 QuasiObserver::invalidate(ob);
339 }
340 if let Some(ob) = observers.get_mut(j) {
341 QuasiObserver::invalidate(ob);
342 }
343 self.untracked_mut().swap(i, j);
344 }
345 }
346
347 pub fn rotate_left(&mut self, n: usize) {
349 if n != 0 && (*self).untracked_ref().len() > 1 {
350 self.tracked_mut().rotate_left(n);
351 }
352 }
353
354 pub fn rotate_right(&mut self, n: usize) {
356 if n != 0 && (*self).untracked_ref().len() > 1 {
357 self.tracked_mut().rotate_right(n);
358 }
359 }
360
361 pub fn push_front(&mut self, value: O::Head) {
363 self.state.front_mutated = true;
364 self.state.inner.get_mut().clear();
365 self.untracked_mut().push_front(value);
366 }
367
368 pub fn pop_front(&mut self) -> Option<O::Head> {
370 let value = self.untracked_mut().pop_front()?;
371 self.state.front_mutated = true;
372 self.state.inner.get_mut().clear();
373 Some(value)
374 }
375
376 pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut O::Head) -> bool) -> Option<O::Head> {
378 let front = self.untracked_mut().front_mut()?;
380 if predicate(front) { self.pop_front() } else { None }
381 }
382
383 pub fn swap_remove_front(&mut self, index: usize) -> Option<O::Head> {
385 let value = self.untracked_mut().swap_remove_front(index)?;
386 self.state.front_mutated = true;
387 self.state.inner.get_mut().clear();
388 Some(value)
389 }
390}
391
392#[cfg(feature = "append")]
393impl<'ob, O, S: ?Sized, D> VecDequeObserver<'ob, O, S, D>
394where
395 D: Unsigned,
396 O: Observer<InnerDepth = Zero, Head: Sized>,
397 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
398{
399 pub fn push_back(&mut self, value: O::Head) {
401 self.untracked_mut().push_back(value);
402 }
403
404 pub fn append(&mut self, other: &mut VecDeque<O::Head>) {
406 self.untracked_mut().append(other);
407 }
408
409 pub fn insert(&mut self, index: usize, value: O::Head) {
411 if index >= self.state.back_append_index {
412 self.untracked_mut().insert(index, value);
413 } else {
414 self.state.inner.get_mut().clear();
415 self.tracked_mut().insert(index, value);
416 }
417 }
418}
419
420#[cfg(any(feature = "append", feature = "truncate"))]
421impl<'ob, O, S: ?Sized, D> VecDequeObserver<'ob, O, S, D>
422where
423 D: Unsigned,
424 O: Observer<InnerDepth = Zero, Head: Sized>,
425 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
426{
427 pub fn pop_back(&mut self) -> Option<O::Head> {
429 let value = self.untracked_mut().pop_back()?;
430 let len = (*self).untracked_ref().len();
431 if len >= self.state.back_append_index {
432 } else if cfg!(feature = "truncate") && len + 1 == self.state.back_append_index {
434 self.state.mark_back_truncate(len);
435 } else {
436 self.state.mark_replace();
437 }
438 Some(value)
439 }
440
441 pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut O::Head) -> bool) -> Option<O::Head> {
443 let back = self.untracked_mut().back_mut()?;
444 if predicate(back) { self.pop_back() } else { None }
445 }
446
447 pub fn clear(&mut self) {
449 if self.state.back_append_index == 0 && !self.state.front_mutated {
450 self.untracked_mut().clear();
451 } else {
452 self.state.inner.get_mut().clear();
453 self.tracked_mut().clear();
454 }
455 }
456
457 pub fn truncate(&mut self, len: usize) {
459 let bai = self.state.back_append_index;
460 if len >= bai {
461 self.untracked_mut().truncate(len);
462 return;
463 }
464 if cfg!(not(feature = "truncate")) || len == 0 {
465 self.state.inner.get_mut().clear();
466 self.tracked_mut().truncate(len);
467 return;
468 }
469 self.state.mark_back_truncate(len);
470 self.untracked_mut().truncate(len);
471 }
472
473 pub fn remove(&mut self, index: usize) -> Option<O::Head> {
475 let bai = self.state.back_append_index;
476 let value = self.untracked_mut().remove(index)?;
477 if index >= bai {
478 } else if cfg!(feature = "truncate") && index + 1 == bai {
480 self.state.mark_back_truncate(index);
481 } else {
482 self.state.mark_replace();
483 }
484 Some(value)
485 }
486
487 pub fn swap_remove_back(&mut self, index: usize) -> Option<O::Head> {
489 let bai = self.state.back_append_index;
490 let value = self.untracked_mut().swap_remove_back(index)?;
491 if index >= bai {
492 } else if cfg!(feature = "truncate") && index + 1 == bai {
494 self.state.mark_back_truncate(index);
495 } else {
496 self.state.mark_replace();
497 }
498 Some(value)
499 }
500
501 pub fn split_off(&mut self, at: usize) -> VecDeque<O::Head> {
503 let bai = self.state.back_append_index;
504 let split = self.untracked_mut().split_off(at);
505 if at >= bai {
506 } else if cfg!(feature = "truncate") && at > 0 {
508 self.state.mark_back_truncate(at);
509 } else {
510 self.state.mark_replace();
511 }
512 split
513 }
514
515 pub fn retain<F>(&mut self, f: F)
517 where
518 F: FnMut(&O::Head) -> bool,
519 {
520 self.state.inner.get_mut().clear();
521 self.tracked_mut().retain(f);
522 }
523
524 pub fn retain_mut<F>(&mut self, f: F)
526 where
527 F: FnMut(&mut O::Head) -> bool,
528 {
529 self.state.inner.get_mut().clear();
530 self.tracked_mut().retain_mut(f);
531 }
532
533 pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut() -> O::Head) {
535 let bai = self.state.back_append_index;
536 self.untracked_mut().resize_with(new_len, generator);
537 if new_len >= bai {
538 } else if cfg!(feature = "truncate") && new_len > 0 {
540 self.state.mark_back_truncate(new_len);
541 } else {
542 self.state.mark_replace();
543 }
544 }
545
546 pub fn drain<R>(&mut self, range: R) -> Drain<'_, O::Head>
548 where
549 R: RangeBounds<usize>,
550 {
551 let bai = self.state.back_append_index;
552 let start = match range.start_bound() {
553 Bound::Included(&n) => n,
554 Bound::Excluded(&n) => n + 1,
555 Bound::Unbounded => 0,
556 };
557 if start >= bai {
558 return self.untracked_mut().drain(range);
559 }
560 if cfg!(not(feature = "truncate")) || start == 0 {
561 self.state.inner.get_mut().clear();
562 return self.tracked_mut().drain(range);
563 }
564 let end = match range.end_bound() {
565 Bound::Included(&n) => n + 1,
566 Bound::Excluded(&n) => n,
567 Bound::Unbounded => (*self).untracked_ref().len(),
568 };
569 if end < bai {
570 self.state.inner.get_mut().clear();
571 return self.tracked_mut().drain(range);
572 }
573 self.state.mark_back_truncate(start);
574 self.state.inner.get_mut().clear();
575 self.tracked_mut().drain(range)
576 }
577}
578
579#[cfg(any(feature = "append", feature = "truncate"))]
580impl<'ob, O, S: ?Sized, D> VecDequeObserver<'ob, O, S, D>
581where
582 D: Unsigned,
583 O: Observer<InnerDepth = Zero, Head: Sized>,
584 O::Head: Clone,
585 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
586{
587 pub fn resize(&mut self, new_len: usize, value: O::Head) {
589 let bai = self.state.back_append_index;
590 self.untracked_mut().resize(new_len, value);
591 if new_len >= bai {
592 } else if cfg!(feature = "truncate") && new_len > 0 {
594 self.state.mark_back_truncate(new_len);
595 } else {
596 self.state.mark_replace();
597 }
598 }
599}
600
601#[cfg(feature = "append")]
602impl<'ob, O, S: ?Sized, D, U> Extend<U> for VecDequeObserver<'ob, O, S, D>
603where
604 D: Unsigned,
605 O: Observer<InnerDepth = Zero, Head: Sized>,
606 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
607 VecDeque<O::Head>: Extend<U>,
608{
609 fn extend<I: IntoIterator<Item = U>>(&mut self, other: I) {
610 self.untracked_mut().extend(other);
611 }
612}
613
614impl<'ob, O, S: ?Sized, D> Index<usize> for VecDequeObserver<'ob, O, S, D>
615where
616 D: Unsigned,
617 O: Observer<InnerDepth = Zero, Head: Sized>,
618 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
619{
620 type Output = O;
621
622 fn index(&self, index: usize) -> &Self::Output {
623 self.force_index(index).expect("index out of bounds")
624 }
625}
626
627impl<'ob, O, S: ?Sized, D> IndexMut<usize> for VecDequeObserver<'ob, O, S, D>
628where
629 D: Unsigned,
630 O: Observer<InnerDepth = Zero, Head: Sized>,
631 S: AsDerefMut<D, Target = VecDeque<O::Head>>,
632{
633 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
634 self.get_mut(index).expect("index out of bounds")
635 }
636}
637
638impl<'ob, O, S: ?Sized, D> Debug for VecDequeObserver<'ob, O, S, D>
639where
640 D: Unsigned,
641 O: Observer<InnerDepth = Zero, Head: Sized>,
642 O::Head: Debug,
643 S: AsDeref<D, Target = VecDeque<O::Head>>,
644{
645 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
646 f.debug_tuple("VecDequeObserver").field(&self.untracked_ref()).finish()
647 }
648}
649
650impl<'ob, O, S: ?Sized, D, U> PartialEq<VecDeque<U>> for VecDequeObserver<'ob, O, S, D>
651where
652 D: Unsigned,
653 O: Observer<InnerDepth = Zero, Head: Sized>,
654 S: AsDeref<D, Target = VecDeque<O::Head>>,
655 VecDeque<O::Head>: PartialEq<VecDeque<U>>,
656{
657 fn eq(&self, other: &VecDeque<U>) -> bool {
658 self.untracked_ref().eq(other)
659 }
660}
661
662impl<'ob, O1, O2, S1: ?Sized, S2: ?Sized, D1, D2> PartialEq<VecDequeObserver<'ob, O2, S2, D2>>
663 for VecDequeObserver<'ob, O1, S1, D1>
664where
665 D1: Unsigned,
666 D2: Unsigned,
667 O1: Observer<InnerDepth = Zero, Head: Sized>,
668 O2: Observer<InnerDepth = Zero, Head: Sized>,
669 S1: AsDeref<D1, Target = VecDeque<O1::Head>>,
670 S2: AsDeref<D2, Target = VecDeque<O2::Head>>,
671 VecDeque<O1::Head>: PartialEq<VecDeque<O2::Head>>,
672{
673 fn eq(&self, other: &VecDequeObserver<'ob, O2, S2, D2>) -> bool {
674 self.untracked_ref().eq(other.untracked_ref())
675 }
676}
677
678impl<'ob, O, S: ?Sized, D> Eq for VecDequeObserver<'ob, O, S, D>
679where
680 D: Unsigned,
681 O: Observer<InnerDepth = Zero, Head: Sized>,
682 O::Head: Eq,
683 S: AsDeref<D, Target = VecDeque<O::Head>>,
684{
685}
686
687impl<T: Observe> Observe for VecDeque<T> {
688 type Observer<'ob, S, D>
689 = VecDequeObserver<'ob, T::Observer<'ob, T, Zero>, S, D>
690 where
691 Self: 'ob,
692 D: Unsigned,
693 S: AsDerefMut<D, Target = Self> + ?Sized + 'ob;
694
695 type Spec = DefaultSpec;
696}
697
698default_impl_ref_observe! {
699 impl [T: Observe] RefObserve for VecDeque<T>;
700}
701
702#[cfg(test)]
703mod tests {
704 use std::collections::VecDeque;
705
706 use morphix_test_utils::*;
707 use serde_json::json;
708
709 use crate::adapter::Json;
710 use crate::observe::{ObserveExt, SerializeObserverExt};
711
712 #[test]
713 fn no_change_returns_none() {
714 let mut deque = VecDeque::from([1, 2, 3]);
715 let mut ob = deque.__observe();
716 let Json(mutation) = ob.flush().unwrap();
717 assert_eq!(mutation, None);
718 }
719
720 #[test]
721 fn reserve_returns_none() {
722 let mut deque = VecDeque::from([1, 2, 3]);
723 let mut ob = deque.__observe();
724 ob.reserve(100);
725 ob.shrink_to_fit();
726 let Json(mutation) = ob.flush().unwrap();
727 assert_eq!(mutation, None);
728 }
729
730 #[test]
731 fn make_contiguous_returns_none() {
732 let mut deque = VecDeque::new();
733 deque.push_back(1);
734 deque.push_back(2);
735 deque.push_front(0);
736 let mut ob = deque.__observe();
737 ob.make_contiguous();
738 let Json(mutation) = ob.flush().unwrap();
739 assert_eq!(mutation, None);
740 }
741
742 #[test]
743 fn push_back_triggers_append() {
744 let mut deque = VecDeque::from([1]);
745 let mut ob = deque.__observe();
746 ob.push_back(2);
747 ob.push_back(3);
748 let Json(mutation) = ob.flush().unwrap();
749 assert_eq!(mutation, Some(append!(_, json!([2, 3]))));
750 }
751
752 #[test]
753 fn extend_triggers_append() {
754 let mut deque = VecDeque::from([1]);
755 let mut ob = deque.__observe();
756 ob.extend([2, 3]);
757 let Json(mutation) = ob.flush().unwrap();
758 assert_eq!(mutation, Some(append!(_, json!([2, 3]))));
759 }
760
761 #[test]
762 fn append_other_deque() {
763 let mut deque = VecDeque::from([1]);
764 let mut ob = deque.__observe();
765 let mut other = VecDeque::from([4, 5]);
766 ob.append(&mut other);
767 let Json(mutation) = ob.flush().unwrap();
768 assert_eq!(mutation, Some(append!(_, json!([4, 5]))));
769 }
770
771 #[test]
772 fn pop_back_triggers_truncate() {
773 let mut deque = VecDeque::from([1, 2, 3]);
774 let mut ob = deque.__observe();
775 ob.pop_back();
776 ob.pop_back();
777 let Json(mutation) = ob.flush().unwrap();
778 assert_eq!(mutation, Some(truncate!(_, 2)));
779 }
780
781 #[test]
782 fn truncate_method() {
783 let mut deque = VecDeque::from([1, 2, 3, 4, 5]);
784 let mut ob = deque.__observe();
785 ob.truncate(2);
786 let Json(mutation) = ob.flush().unwrap();
787 assert_eq!(mutation, Some(truncate!(_, 3)));
788 }
789
790 #[test]
791 fn pop_back_then_push_back() {
792 let mut deque = VecDeque::from([1, 2, 3]);
793 let mut ob = deque.__observe();
794 ob.pop_back();
795 ob.push_back(4);
796 let Json(mutation) = ob.flush().unwrap();
797 assert_eq!(mutation, Some(batch!(_, truncate!(_, 1), append!(_, json!([4])))));
798 }
799
800 #[test]
801 fn pop_back_from_appended_region() {
802 let mut deque = VecDeque::from([1]);
803 let mut ob = deque.__observe();
804 ob.push_back(2);
805 ob.push_back(3);
806 ob.pop_back(); let Json(mutation) = ob.flush().unwrap();
808 assert_eq!(mutation, Some(append!(_, json!([2]))));
809 }
810
811 #[test]
812 fn push_front_triggers_replace() {
813 let mut deque = VecDeque::from([1, 2]);
814 let mut ob = deque.__observe();
815 ob.push_front(0);
816 let Json(mutation) = ob.flush().unwrap();
817 assert_eq!(mutation, Some(replace!(_, json!([0, 1, 2]))));
818 }
819
820 #[test]
821 fn pop_front_triggers_replace() {
822 let mut deque = VecDeque::from([1, 2, 3]);
823 let mut ob = deque.__observe();
824 ob.pop_front();
825 let Json(mutation) = ob.flush().unwrap();
826 assert_eq!(mutation, Some(replace!(_, json!([2, 3]))));
827 }
828
829 #[test]
830 fn pop_front_if_true_triggers_replace() {
831 let mut deque = VecDeque::from([1, 2, 3]);
832 let mut ob = deque.__observe();
833 let result = ob.pop_front_if(|x| *x == 1);
834 assert_eq!(result, Some(1));
835 let Json(mutation) = ob.flush().unwrap();
836 assert_eq!(mutation, Some(replace!(_, json!([2, 3]))));
837 }
838
839 #[test]
840 fn pop_front_if_false_returns_none() {
841 let mut deque = VecDeque::from([1, 2, 3]);
842 let mut ob = deque.__observe();
843 let result = ob.pop_front_if(|x| *x == 99);
844 assert_eq!(result, None);
845 let Json(mutation) = ob.flush().unwrap();
846 assert_eq!(mutation, None);
847 }
848
849 #[test]
850 fn push_front_overrides_back_append() {
851 let mut deque = VecDeque::from([1]);
852 let mut ob = deque.__observe();
853 ob.push_back(2);
854 ob.push_front(0); let Json(mutation) = ob.flush().unwrap();
856 assert_eq!(mutation, Some(replace!(_, json!([0, 1, 2]))));
857 }
858
859 #[test]
860 fn deref_mut_triggers_replace() {
861 let mut deque = VecDeque::from([1, 2]);
862 let mut ob = deque.__observe();
863 ob.retain(|x| *x > 1);
864 let Json(mutation) = ob.flush().unwrap();
865 assert_eq!(mutation, Some(replace!(_, json!([2]))));
866 }
867
868 #[test]
869 fn empty_deque_no_mutation() {
870 let mut deque: VecDeque<i32> = VecDeque::new();
871 let mut ob = deque.__observe();
872 let Json(mutation) = ob.flush().unwrap();
873 assert_eq!(mutation, None);
874 }
875
876 #[test]
877 fn empty_deque_push_back() {
878 let mut deque: VecDeque<i32> = VecDeque::new();
879 let mut ob = deque.__observe();
880 ob.push_back(1);
881 let Json(mutation) = ob.flush().unwrap();
882 assert_eq!(mutation, Some(append!(_, json!([1]))));
883 }
884
885 #[test]
886 fn empty_deque_push_front() {
887 let mut deque: VecDeque<i32> = VecDeque::new();
888 let mut ob = deque.__observe();
889 ob.push_front(1);
890 let Json(mutation) = ob.flush().unwrap();
891 assert_eq!(mutation, Some(replace!(_, json!([1]))));
892 }
893
894 #[test]
895 fn clear_empty_deque() {
896 let mut deque: VecDeque<i32> = VecDeque::new();
897 let mut ob = deque.__observe();
898 ob.clear();
899 let Json(mutation) = ob.flush().unwrap();
900 assert_eq!(mutation, None);
901 }
902
903 #[test]
904 fn clear_nonempty_deque() {
905 let mut deque = VecDeque::from([1, 2, 3]);
906 let mut ob = deque.__observe();
907 ob.clear();
908 let Json(mutation) = ob.flush().unwrap();
909 assert_eq!(mutation, Some(replace!(_, json!([]))));
910 }
911
912 #[test]
913 fn split_off_from_existing() {
914 let mut deque = VecDeque::from([1, 2, 3, 4]);
915 let mut ob = deque.__observe();
916 let split = ob.split_off(2);
917 assert_eq!(split, VecDeque::from([3, 4]));
918 let Json(mutation) = ob.flush().unwrap();
919 assert_eq!(mutation, Some(truncate!(_, 2)));
920 }
921
922 #[test]
923 fn split_off_from_appended() {
924 let mut deque = VecDeque::from([1]);
925 let mut ob = deque.__observe();
926 ob.push_back(2);
927 ob.push_back(3);
928 let split = ob.split_off(2);
929 assert_eq!(split, VecDeque::from([3]));
930 let Json(mutation) = ob.flush().unwrap();
931 assert_eq!(mutation, Some(append!(_, json!([2]))));
932 }
933
934 #[test]
935 fn remove_at_back_append_boundary() {
936 let mut deque = VecDeque::from([1, 2, 3]);
937 let mut ob = deque.__observe();
938 let val = ob.remove(2);
939 assert_eq!(val, Some(3));
940 let Json(mutation) = ob.flush().unwrap();
941 assert_eq!(mutation, Some(truncate!(_, 1)));
942 }
943
944 #[test]
945 fn remove_from_middle_triggers_replace() {
946 let mut deque = VecDeque::from([1, 2, 3, 4]);
947 let mut ob = deque.__observe();
948 let val = ob.remove(1);
949 assert_eq!(val, Some(2));
950 let Json(mutation) = ob.flush().unwrap();
951 assert_eq!(mutation, Some(replace!(_, json!([1, 3, 4]))));
952 }
953
954 #[test]
955 fn insert_in_appended_region() {
956 let mut deque = VecDeque::from([1]);
957 let mut ob = deque.__observe();
958 ob.push_back(2);
959 ob.insert(2, 3); let Json(mutation) = ob.flush().unwrap();
961 assert_eq!(mutation, Some(append!(_, json!([2, 3]))));
962 }
963
964 #[test]
965 fn insert_in_existing_region() {
966 let mut deque = VecDeque::from([1, 2, 3]);
967 let mut ob = deque.__observe();
968 ob.insert(1, 99);
969 let Json(mutation) = ob.flush().unwrap();
970 assert_eq!(mutation, Some(replace!(_, json!([1, 99, 2, 3]))));
971 }
972
973 #[test]
974 fn swap_remove_front_triggers_replace() {
975 let mut deque = VecDeque::from([1, 2, 3]);
976 let mut ob = deque.__observe();
977 let val = ob.swap_remove_front(1);
978 assert_eq!(val, Some(2));
979 let Json(mutation) = ob.flush().unwrap();
980 assert_eq!(mutation, Some(replace!(_, json!([1, 3]))));
981 }
982
983 #[test]
984 fn multiple_flushes() {
985 let mut deque = VecDeque::from([1, 2]);
986 let mut ob = deque.__observe();
987 ob.push_back(3);
988 let Json(m1) = ob.flush().unwrap();
989 assert_eq!(m1, Some(append!(_, json!([3]))));
990 let Json(m2) = ob.flush().unwrap();
992 assert_eq!(m2, None);
993 ob.pop_back();
995 let Json(m3) = ob.flush().unwrap();
996 assert_eq!(m3, Some(truncate!(_, 1)));
997 }
998
999 #[test]
1000 fn resize_shrink() {
1001 let mut deque = VecDeque::from([1, 2, 3, 4, 5]);
1002 let mut ob = deque.__observe();
1003 ob.resize(2, 0);
1004 let Json(mutation) = ob.flush().unwrap();
1005 assert_eq!(mutation, Some(truncate!(_, 3)));
1006 }
1007
1008 #[test]
1009 fn resize_grow() {
1010 let mut deque = VecDeque::from([1]);
1011 let mut ob = deque.__observe();
1012 ob.resize(3, 0);
1013 let Json(mutation) = ob.flush().unwrap();
1014 assert_eq!(mutation, Some(append!(_, json!([0, 0]))));
1015 }
1016
1017 #[test]
1018 fn pop_back_if_true() {
1019 let mut deque = VecDeque::from([1, 2, 3]);
1020 let mut ob = deque.__observe();
1021 let result = ob.pop_back_if(|x| *x == 3);
1022 assert_eq!(result, Some(3));
1023 let Json(mutation) = ob.flush().unwrap();
1024 assert_eq!(mutation, Some(truncate!(_, 1)));
1025 }
1026
1027 #[test]
1028 fn pop_back_if_false() {
1029 let mut deque = VecDeque::from([1, 2, 3]);
1030 let mut ob = deque.__observe();
1031 let result = ob.pop_back_if(|x| *x == 99);
1032 assert_eq!(result, None);
1033 let Json(mutation) = ob.flush().unwrap();
1034 assert_eq!(mutation, None);
1035 }
1036
1037 #[test]
1038 fn drain_from_appended() {
1039 let mut deque = VecDeque::from([1]);
1040 let mut ob = deque.__observe();
1041 ob.push_back(2);
1042 ob.push_back(3);
1043 let drained: Vec<_> = ob.drain(1..).collect();
1044 assert_eq!(drained, vec![2, 3]);
1045 let Json(mutation) = ob.flush().unwrap();
1046 assert_eq!(mutation, None); }
1048
1049 #[test]
1050 fn drain_straddles_boundary() {
1051 let mut deque = VecDeque::from([1, 2, 3]);
1052 let mut ob = deque.__observe();
1053 ob.push_back(4);
1054 let drained: Vec<_> = ob.drain(1..).collect();
1055 assert_eq!(drained, vec![2, 3, 4]);
1056 let Json(mutation) = ob.flush().unwrap();
1057 assert_eq!(mutation, Some(replace!(_, json!([1]))));
1059 }
1060
1061 #[test]
1062 fn index_mut_triggers_replace() {
1063 let mut deque = VecDeque::from([1i32, 2, 3]);
1064 let mut ob = deque.__observe();
1065 **ob[1] = 99;
1066 let Json(mutation) = ob.flush().unwrap();
1067 assert_eq!(mutation, Some(replace!(-2, json!(99))));
1068 }
1069
1070 #[test]
1071 fn index_returns_inner_observer() {
1072 let mut deque = VecDeque::from(["hello".to_string(), "world".to_string()]);
1073 let mut ob = deque.__observe();
1074 assert_eq!(ob[0], "hello");
1076 assert_eq!(ob[1], "world");
1077 let Json(mutation) = ob.flush().unwrap();
1078 assert_eq!(mutation, None);
1079 }
1080
1081 #[test]
1082 fn modify_element_via_inner_observer() {
1083 let mut deque = VecDeque::from(["hello".to_string(), "world".to_string()]);
1084 let mut ob = deque.__observe();
1085 ob[0].push_str("!");
1088 let Json(mutation) = ob.flush().unwrap();
1089 assert_eq!(mutation, Some(append!(-2, json!("!"))));
1090 }
1091
1092 #[test]
1093 fn modify_multiple_elements_via_inner_observer() {
1094 let mut deque = VecDeque::from(["a".to_string(), "b".to_string(), "c".to_string()]);
1095 let mut ob = deque.__observe();
1096 ob[0].push_str("1");
1097 ob[2].push_str("3");
1098 let Json(mutation) = ob.flush().unwrap();
1099 assert_eq!(
1100 mutation,
1101 Some(batch!(_, append!(-1, json!("3")), append!(-3, json!("1"))))
1102 );
1103 }
1104
1105 #[test]
1106 fn get_mut_returns_observer() {
1107 let mut deque = VecDeque::from(["foo".to_string(), "bar".to_string()]);
1108 let mut ob = deque.__observe();
1109 let elem = ob.get_mut(1).unwrap();
1110 elem.push_str("baz");
1111 let Json(mutation) = ob.flush().unwrap();
1112 assert_eq!(mutation, Some(append!(-1, json!("baz"))));
1113 }
1114
1115 #[test]
1116 fn front_mut_returns_observer() {
1117 let mut deque = VecDeque::from(["first".to_string(), "second".to_string()]);
1118 let mut ob = deque.__observe();
1119 let front = ob.front_mut().unwrap();
1120 front.push_str("!");
1121 let Json(mutation) = ob.flush().unwrap();
1122 assert_eq!(mutation, Some(append!(-2, json!("!"))));
1123 }
1124
1125 #[test]
1126 fn back_mut_returns_observer() {
1127 let mut deque = VecDeque::from(["first".to_string(), "second".to_string()]);
1128 let mut ob = deque.__observe();
1129 let back = ob.back_mut().unwrap();
1130 back.push_str("!");
1131 let Json(mutation) = ob.flush().unwrap();
1132 assert_eq!(mutation, Some(append!(-1, json!("!"))));
1133 }
1134
1135 #[test]
1136 fn iter_mut_returns_observers() {
1137 let mut deque = VecDeque::from(["a".to_string(), "b".to_string(), "c".to_string()]);
1138 let mut ob = deque.__observe();
1139 for elem in ob.iter_mut() {
1140 elem.push_str("!");
1141 }
1142 let Json(mutation) = ob.flush().unwrap();
1143 assert_eq!(
1146 mutation,
1147 Some(batch!(
1148 _,
1149 append!(-1, json!("!")),
1150 append!(-2, json!("!")),
1151 append!(-3, json!("!"))
1152 ))
1153 );
1154 }
1155
1156 #[test]
1157 fn make_contiguous_returns_observer_slice() {
1158 let mut deque = VecDeque::from(["x".to_string(), "y".to_string()]);
1159 let mut ob = deque.__observe();
1160 let slice = ob.make_contiguous();
1161 slice[0].push_str("1");
1162 let Json(mutation) = ob.flush().unwrap();
1163 assert_eq!(mutation, Some(append!(-2, json!("1"))));
1164 }
1165
1166 #[test]
1167 fn modify_then_append() {
1168 let mut deque = VecDeque::from(["a".to_string()]);
1169 let mut ob = deque.__observe();
1170 ob[0].push_str("!");
1171 ob.push_back("b".to_string());
1172 let Json(mutation) = ob.flush().unwrap();
1173 assert_eq!(
1175 mutation,
1176 Some(batch!(_, append!(_, json!(["b"])), append!(-2, json!("!"))))
1177 );
1178 }
1179
1180 #[test]
1181 fn no_modify_then_append() {
1182 let mut deque = VecDeque::from(["a".to_string()]);
1183 let mut ob = deque.__observe();
1184 let _ = &ob[0];
1186 ob.push_back("b".to_string());
1187 let Json(mutation) = ob.flush().unwrap();
1188 assert_eq!(mutation, Some(append!(_, json!(["b"]))));
1189 }
1190
1191 #[test]
1192 fn modify_element_then_pop_back() {
1193 let mut deque = VecDeque::from(["a".to_string(), "b".to_string(), "c".to_string()]);
1194 let mut ob = deque.__observe();
1195 ob[0].push_str("!");
1196 ob.pop_back();
1197 let Json(mutation) = ob.flush().unwrap();
1198 assert_eq!(mutation, Some(batch!(_, truncate!(_, 1), append!(-2, json!("!")))));
1200 }
1201
1202 #[test]
1203 fn index_read_only_no_mutation() {
1204 let mut deque = VecDeque::from(["hello".to_string(), "world".to_string()]);
1205 let mut ob = deque.__observe();
1206 let _val = &ob[0];
1208 let _val2 = &ob[1];
1209 let Json(mutation) = ob.flush().unwrap();
1210 assert_eq!(mutation, None);
1211 }
1212
1213 #[test]
1214 fn pop_push_clears_stale_observer_state() {
1215 let mut deque = VecDeque::from(["a".to_string(), "b".to_string(), "ab".to_string()]);
1216 let mut ob = deque.__observe();
1217
1218 ob[2].truncate(1);
1220 ob.pop_back();
1221 ob.push_back("cd".to_string());
1222 let Json(mutation) = ob.flush().unwrap();
1223 assert!(mutation.is_some()); assert_eq!(ob[2], "cd");
1227 let Json(mutation) = ob.flush().unwrap();
1228 assert_eq!(mutation, None);
1229 }
1230}