1use serde::{Serialize, Serializer};
2use std::borrow::Borrow;
3use std::collections::{HashMap, HashSet, VecDeque};
4use std::fmt::Formatter;
5use std::marker::PhantomData;
6use std::sync::Arc;
7
8pub use map::Map;
9pub use map::MapRef;
10pub use text::Text;
11pub use text::TextRef;
12
13use crate::block::{Item, ItemContent, ItemPtr, Prelim};
14use crate::branch::{Branch, BranchPtr};
15use crate::encoding::read::Error;
16use crate::transaction::TransactionMut;
17use crate::types::array::{ArrayEvent, ArrayRef};
18use crate::types::map::MapEvent;
19use crate::types::text::TextEvent;
20#[cfg(feature = "weak")]
21use crate::types::weak::{LinkSource, WeakEvent, WeakRef};
22use crate::types::xml::{XmlElementRef, XmlEvent, XmlTextEvent, XmlTextRef};
23use crate::updates::decoder::{Decode, Decoder};
24use crate::updates::encoder::{Encode, Encoder};
25use crate::*;
26
27pub mod array;
28pub mod map;
29pub mod text;
30#[cfg(feature = "weak")]
31pub mod weak;
32pub mod xml;
33
34pub const TYPE_REFS_ARRAY: u8 = 0;
36
37pub const TYPE_REFS_MAP: u8 = 1;
39
40pub const TYPE_REFS_TEXT: u8 = 2;
42
43pub const TYPE_REFS_XML_ELEMENT: u8 = 3;
45
46pub const TYPE_REFS_XML_FRAGMENT: u8 = 4;
48
49pub const TYPE_REFS_XML_HOOK: u8 = 5;
51
52pub const TYPE_REFS_XML_TEXT: u8 = 6;
54
55pub const TYPE_REFS_WEAK: u8 = 7;
57
58pub const TYPE_REFS_DOC: u8 = 9;
60
61pub const TYPE_REFS_UNDEFINED: u8 = 15;
64
65#[repr(u8)]
66#[derive(Debug, Clone, Eq, PartialEq)]
67pub enum TypeRef {
68 Array = TYPE_REFS_ARRAY,
69 Map = TYPE_REFS_MAP,
70 Text = TYPE_REFS_TEXT,
71 XmlElement(Arc<str>) = TYPE_REFS_XML_ELEMENT,
72 XmlFragment = TYPE_REFS_XML_FRAGMENT,
73 XmlHook = TYPE_REFS_XML_HOOK,
74 XmlText = TYPE_REFS_XML_TEXT,
75 SubDoc = TYPE_REFS_DOC,
76 #[cfg(feature = "weak")]
77 WeakLink(Arc<LinkSource>) = TYPE_REFS_WEAK,
78 Undefined = TYPE_REFS_UNDEFINED,
79}
80
81impl TypeRef {
82 pub fn kind(&self) -> u8 {
83 match self {
84 TypeRef::Array => TYPE_REFS_ARRAY,
85 TypeRef::Map => TYPE_REFS_MAP,
86 TypeRef::Text => TYPE_REFS_TEXT,
87 TypeRef::XmlElement(_) => TYPE_REFS_XML_ELEMENT,
88 TypeRef::XmlFragment => TYPE_REFS_XML_FRAGMENT,
89 TypeRef::XmlHook => TYPE_REFS_XML_HOOK,
90 TypeRef::XmlText => TYPE_REFS_XML_TEXT,
91 TypeRef::SubDoc => TYPE_REFS_DOC,
92 #[cfg(feature = "weak")]
93 TypeRef::WeakLink(_) => TYPE_REFS_WEAK,
94 TypeRef::Undefined => TYPE_REFS_UNDEFINED,
95 }
96 }
97
98 #[cfg(feature = "weak")]
99 fn encode_weak_link<E: Encoder>(data: &LinkSource, encoder: &mut E) {
100 encoder.write_type_ref(TYPE_REFS_WEAK);
101 let mut info = 0u8;
102 let is_single = data.is_single();
103 if !is_single {
104 info |= WEAK_REF_FLAGS_QUOTE;
105 };
106 if data.quote_start.is_root() || data.quote_end.is_root() {
107 info |= WEAK_REF_FLAGS_PARENT_ROOT;
108 }
109 if !data.quote_start.is_relative() {
110 info |= WEAK_REF_FLAGS_START_UNBOUNDED;
111 }
112 if !data.quote_end.is_relative() {
113 info |= WEAK_REF_FLAGS_END_UNBOUNDED;
114 }
115 if data.quote_start.assoc == Assoc::After {
116 info |= WEAK_REF_FLAGS_START_ASSOC;
117 }
118 if data.quote_end.assoc == Assoc::After {
119 info |= WEAK_REF_FLAGS_END_ASSOC;
120 }
121 encoder.write_u8(info);
122 match data.quote_start.scope() {
123 IndexScope::Relative(id) | IndexScope::Nested(id) => {
124 encoder.write_var(id.client);
125 encoder.write_var(id.clock);
126 }
127 IndexScope::Root(name) => {
128 encoder.write_string(name);
129 }
130 }
131
132 match data.quote_end.scope() {
133 IndexScope::Relative(id) if !is_single => {
134 encoder.write_var(id.client);
135 encoder.write_var(id.clock);
136 }
137 IndexScope::Relative(id) => {
138 }
140 IndexScope::Nested(id) => {
141 encoder.write_var(id.client);
142 encoder.write_var(id.clock);
143 }
144 IndexScope::Root(name) => {
145 encoder.write_string(name);
146 }
147 }
148 }
149
150 #[cfg(feature = "weak")]
151 fn decode_weak_link<D: Decoder>(decoder: &mut D) -> Result<Arc<LinkSource>, Error> {
152 let flags = decoder.read_u8()?;
153 let is_single = flags & WEAK_REF_FLAGS_QUOTE == 0;
154 let start_assoc = if flags & WEAK_REF_FLAGS_START_ASSOC == WEAK_REF_FLAGS_START_ASSOC {
155 Assoc::After
156 } else {
157 Assoc::Before
158 };
159 let end_assoc = if flags & WEAK_REF_FLAGS_END_ASSOC == WEAK_REF_FLAGS_END_ASSOC {
160 Assoc::After
161 } else {
162 Assoc::Before
163 };
164 let is_start_unbounded =
165 flags & WEAK_REF_FLAGS_START_UNBOUNDED == WEAK_REF_FLAGS_START_UNBOUNDED;
166 let is_end_unbounded = flags & WEAK_REF_FLAGS_END_UNBOUNDED == WEAK_REF_FLAGS_END_UNBOUNDED;
167 let is_parent_root = flags & WEAK_REF_FLAGS_PARENT_ROOT == WEAK_REF_FLAGS_PARENT_ROOT;
168 let start_scope = if is_start_unbounded {
169 if is_parent_root {
170 let name = decoder.read_string()?;
171 IndexScope::Root(name.into())
172 } else {
173 IndexScope::Nested(ID::new(decoder.read_var()?, decoder.read_var()?))
174 }
175 } else {
176 IndexScope::Relative(ID::new(decoder.read_var()?, decoder.read_var()?))
177 };
178
179 let end_scope = if is_end_unbounded {
180 if is_parent_root {
181 let name = decoder.read_string()?;
182 IndexScope::Root(name.into())
183 } else {
184 IndexScope::Nested(ID::new(decoder.read_var()?, decoder.read_var()?))
185 }
186 } else if is_single {
187 start_scope.clone()
188 } else {
189 IndexScope::Relative(ID::new(decoder.read_var()?, decoder.read_var()?))
190 };
191 let start = StickyIndex::new(start_scope, start_assoc);
192 let end = StickyIndex::new(end_scope, end_assoc);
193 Ok(Arc::new(LinkSource::new(start, end)))
194 }
195}
196
197impl std::fmt::Display for TypeRef {
198 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
199 match self {
200 TypeRef::Array => write!(f, "Array"),
201 TypeRef::Map => write!(f, "Map"),
202 TypeRef::Text => write!(f, "Text"),
203 TypeRef::XmlElement(name) => write!(f, "XmlElement({})", name),
204 TypeRef::XmlFragment => write!(f, "XmlFragment"),
205 TypeRef::XmlHook => write!(f, "XmlHook"),
206 TypeRef::XmlText => write!(f, "XmlText"),
207 TypeRef::SubDoc => write!(f, "Doc"),
208 #[cfg(feature = "weak")]
209 TypeRef::WeakLink(_) => write!(f, "WeakRef"),
210 TypeRef::Undefined => write!(f, "(undefined)"),
211 }
212 }
213}
214
215const WEAK_REF_FLAGS_QUOTE: u8 = 0b0000_0001;
217const WEAK_REF_FLAGS_START_ASSOC: u8 = 0b0000_0010;
219const WEAK_REF_FLAGS_END_ASSOC: u8 = 0b0000_0100;
221const WEAK_REF_FLAGS_START_UNBOUNDED: u8 = 0b0000_1000;
223const WEAK_REF_FLAGS_END_UNBOUNDED: u8 = 0b0001_0000;
225const WEAK_REF_FLAGS_PARENT_ROOT: u8 = 0b0010_0000;
227
228impl Encode for TypeRef {
229 fn encode<E: Encoder>(&self, encoder: &mut E) {
230 match self {
231 TypeRef::Array => encoder.write_type_ref(TYPE_REFS_ARRAY),
232 TypeRef::Map => encoder.write_type_ref(TYPE_REFS_MAP),
233 TypeRef::Text => encoder.write_type_ref(TYPE_REFS_TEXT),
234 TypeRef::XmlElement(name) => {
235 encoder.write_type_ref(TYPE_REFS_XML_ELEMENT);
236 encoder.write_key(&name);
237 }
238 TypeRef::XmlFragment => encoder.write_type_ref(TYPE_REFS_XML_FRAGMENT),
239 TypeRef::XmlHook => encoder.write_type_ref(TYPE_REFS_XML_HOOK),
240 TypeRef::XmlText => encoder.write_type_ref(TYPE_REFS_XML_TEXT),
241 TypeRef::SubDoc => encoder.write_type_ref(TYPE_REFS_DOC),
242 #[cfg(feature = "weak")]
243 TypeRef::WeakLink(data) => Self::encode_weak_link(data, encoder),
244 TypeRef::Undefined => encoder.write_type_ref(TYPE_REFS_UNDEFINED),
245 }
246 }
247}
248
249impl Decode for TypeRef {
250 fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, Error> {
251 let type_ref = decoder.read_type_ref()?;
252 match type_ref {
253 TYPE_REFS_ARRAY => Ok(TypeRef::Array),
254 TYPE_REFS_MAP => Ok(TypeRef::Map),
255 TYPE_REFS_TEXT => Ok(TypeRef::Text),
256 TYPE_REFS_XML_ELEMENT => Ok(TypeRef::XmlElement(decoder.read_key()?)),
257 TYPE_REFS_XML_FRAGMENT => Ok(TypeRef::XmlFragment),
258 TYPE_REFS_XML_HOOK => Ok(TypeRef::XmlHook),
259 TYPE_REFS_XML_TEXT => Ok(TypeRef::XmlText),
260 TYPE_REFS_DOC => Ok(TypeRef::SubDoc),
261 #[cfg(feature = "weak")]
262 TYPE_REFS_WEAK => {
263 let source = Self::decode_weak_link(decoder)?;
264 Ok(TypeRef::WeakLink(source))
265 }
266 TYPE_REFS_UNDEFINED => Ok(TypeRef::Undefined),
267 _ => Err(Error::UnexpectedValue),
268 }
269 }
270}
271
272#[cfg(feature = "sync")]
273pub trait Observable: AsRef<Branch> {
274 type Event;
275
276 fn observe<F>(&self, f: F) -> Subscription
286 where
287 F: Fn(&TransactionMut, &Self::Event) + Send + Sync + 'static,
288 Event: AsRef<Self::Event>,
289 {
290 let mut branch = BranchPtr::from(self.as_ref());
291 branch.observe(move |txn, e| {
292 let mapped_event = e.as_ref();
293 f(txn, mapped_event)
294 })
295 }
296
297 fn observe_with<K, F>(&self, key: K, f: F)
307 where
308 K: Into<Origin>,
309 F: Fn(&TransactionMut, &Self::Event) + Send + Sync + 'static,
310 Event: AsRef<Self::Event>,
311 {
312 let mut branch = BranchPtr::from(self.as_ref());
313 branch.observe_with(key.into(), move |txn, e| {
314 let mapped_event = e.as_ref();
315 f(txn, mapped_event)
316 })
317 }
318
319 fn unobserve<K: Into<Origin>>(&self, key: K) -> bool {
321 let mut branch = BranchPtr::from(self.as_ref());
322 branch.unobserve(&key.into())
323 }
324}
325
326#[cfg(not(feature = "sync"))]
327pub trait Observable: AsRef<Branch> {
328 type Event;
329
330 fn observe<F>(&self, f: F) -> Subscription
340 where
341 F: Fn(&TransactionMut, &Self::Event) + 'static,
342 Event: AsRef<Self::Event>,
343 {
344 let mut branch = BranchPtr::from(self.as_ref());
345 branch.observe(move |txn, e| {
346 let mapped_event = e.as_ref();
347 f(txn, mapped_event)
348 })
349 }
350
351 fn observe_with<K, F>(&self, key: K, f: F)
361 where
362 K: Into<Origin>,
363 F: Fn(&TransactionMut, &Self::Event) + 'static,
364 Event: AsRef<Self::Event>,
365 {
366 let mut branch = BranchPtr::from(self.as_ref());
367 branch.observe_with(key.into(), move |txn, e| {
368 let mapped_event = e.as_ref();
369 f(txn, mapped_event)
370 })
371 }
372
373 fn unobserve<K: Into<Origin>>(&self, key: K) -> bool {
375 let mut branch = BranchPtr::from(self.as_ref());
376 branch.unobserve(&key.into())
377 }
378}
379
380pub trait GetString {
382 fn get_string<T: ReadTxn>(&self, txn: &T) -> String;
384}
385
386pub trait RootRef: SharedRef {
397 fn type_ref() -> TypeRef;
398
399 fn root<N: Into<Arc<str>>>(name: N) -> Root<Self> {
401 Root::new(name)
402 }
403}
404
405pub trait SharedRef: From<BranchPtr> + AsRef<Branch> {
407 fn hook(&self) -> Hook<Self> {
409 let branch = self.as_ref();
410 Hook::from(branch.id())
411 }
412}
413
414pub trait AsPrelim {
417 type Prelim: Prelim<Return = Self>;
418
419 fn as_prelim<T: ReadTxn>(&self, txn: &T) -> Self::Prelim;
422}
423
424pub trait DefaultPrelim {
427 type Prelim: Prelim<Return = Self>;
428
429 fn default_prelim() -> Self::Prelim;
432}
433
434#[cfg(feature = "sync")]
437pub trait DeepObservable: AsRef<Branch> {
438 fn observe_deep<F>(&self, f: F) -> Subscription
449 where
450 F: Fn(&TransactionMut, &Events) + Send + Sync + 'static,
451 {
452 let branch = self.as_ref();
453 branch.deep_observers.subscribe(Box::new(f))
454 }
455
456 fn observe_deep_with<K, F>(&self, key: K, f: F)
467 where
468 K: Into<Origin>,
469 F: Fn(&TransactionMut, &Events) + Send + Sync + 'static,
470 {
471 let branch = self.as_ref();
472 branch
473 .deep_observers
474 .subscribe_with(key.into(), Box::new(f))
475 }
476
477 fn unobserve_deep<K: Into<Origin>>(&self, key: K) -> bool {
480 let branch = self.as_ref();
481 branch.deep_observers.unsubscribe(&key.into())
482 }
483}
484
485#[cfg(not(feature = "sync"))]
488pub trait DeepObservable: AsRef<Branch> {
489 fn observe_deep<F>(&self, f: F) -> Subscription
500 where
501 F: Fn(&TransactionMut, &Events) + 'static,
502 {
503 let branch = self.as_ref();
504 branch.deep_observers.subscribe(Box::new(f))
505 }
506
507 fn observe_deep_with<K, F>(&self, key: K, f: F)
518 where
519 K: Into<Origin>,
520 F: Fn(&TransactionMut, &Events) + 'static,
521 {
522 let branch = self.as_ref();
523 branch
524 .deep_observers
525 .subscribe_with(key.into(), Box::new(f))
526 }
527
528 fn unobserve_deep<K: Into<Origin>>(&self, key: K) -> bool {
531 let branch = self.as_ref();
532 branch.deep_observers.unsubscribe(&key.into())
533 }
534}
535
536impl std::fmt::Display for Branch {
537 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
538 match self.type_ref() {
539 TypeRef::Array => {
540 if let Some(ptr) = self.start {
541 write!(f, "YArray(start: {})", ptr)
542 } else {
543 write!(f, "YArray")
544 }
545 }
546 TypeRef::Map => {
547 write!(f, "YMap(")?;
548 let mut iter = self.map.iter();
549 if let Some((k, v)) = iter.next() {
550 write!(f, "'{}': {}", k, v)?;
551 }
552 while let Some((k, v)) = iter.next() {
553 write!(f, ", '{}': {}", k, v)?;
554 }
555 write!(f, ")")
556 }
557 TypeRef::Text => {
558 if let Some(ptr) = self.start.as_ref() {
559 write!(f, "YText(start: {})", ptr)
560 } else {
561 write!(f, "YText")
562 }
563 }
564 TypeRef::XmlFragment => {
565 write!(f, "YXmlFragment")?;
566 if let Some(start) = self.start.as_ref() {
567 write!(f, "(start: {})", start)?;
568 }
569 Ok(())
570 }
571 TypeRef::XmlElement(name) => {
572 write!(f, "YXmlElement('{}',", name)?;
573 if let Some(start) = self.start.as_ref() {
574 write!(f, "(start: {})", start)?;
575 }
576 if !self.map.is_empty() {
577 write!(f, " {{")?;
578 let mut iter = self.map.iter();
579 if let Some((k, v)) = iter.next() {
580 write!(f, "'{}': {}", k, v)?;
581 }
582 while let Some((k, v)) = iter.next() {
583 write!(f, ", '{}': {}", k, v)?;
584 }
585 write!(f, "}}")?;
586 }
587 Ok(())
588 }
589 TypeRef::XmlHook => {
590 write!(f, "YXmlHook(")?;
591 let mut iter = self.map.iter();
592 if let Some((k, v)) = iter.next() {
593 write!(f, "'{}': {}", k, v)?;
594 }
595 while let Some((k, v)) = iter.next() {
596 write!(f, ", '{}': {}", k, v)?;
597 }
598 write!(f, ")")
599 }
600 TypeRef::XmlText => {
601 if let Some(ptr) = self.start {
602 write!(f, "YXmlText(start: {})", ptr)
603 } else {
604 write!(f, "YXmlText")
605 }
606 }
607 TypeRef::SubDoc => {
608 write!(f, "Subdoc")
609 }
610 #[cfg(feature = "weak")]
611 TypeRef::WeakLink(w) => {
612 if w.is_single() {
613 write!(f, "WeakRef({})", w.quote_start)
614 } else {
615 write!(f, "WeakRef({}..{})", w.quote_start, w.quote_end)
616 }
617 }
618 TypeRef::Undefined => {
619 write!(f, "UnknownRef")?;
620 if let Some(start) = self.start.as_ref() {
621 write!(f, "(start: {})", start)?;
622 }
623 if !self.map.is_empty() {
624 write!(f, " {{")?;
625 let mut iter = self.map.iter();
626 if let Some((k, v)) = iter.next() {
627 write!(f, "'{}': {}", k, v)?;
628 }
629 while let Some((k, v)) = iter.next() {
630 write!(f, ", '{}': {}", k, v)?;
631 }
632 write!(f, "}}")?;
633 }
634 Ok(())
635 }
636 }
637 }
638}
639
640#[derive(Debug)]
641pub(crate) struct Entries<'a, B, T> {
642 iter: std::collections::hash_map::Iter<'a, Arc<str>, ItemPtr>,
643 txn: B,
644 _marker: PhantomData<T>,
645}
646
647impl<'a, B, T: ReadTxn> Entries<'a, B, T>
648where
649 B: Borrow<T>,
650 T: ReadTxn,
651{
652 pub fn new(source: &'a HashMap<Arc<str>, ItemPtr>, txn: B) -> Self {
653 Entries {
654 iter: source.iter(),
655 txn,
656 _marker: PhantomData::default(),
657 }
658 }
659}
660
661impl<'a, T: ReadTxn> Entries<'a, &'a T, T>
662where
663 T: Borrow<T> + ReadTxn,
664{
665 pub fn from_ref(source: &'a HashMap<Arc<str>, ItemPtr>, txn: &'a T) -> Self {
666 Entries::new(source, txn)
667 }
668}
669
670impl<'a, B, T> Iterator for Entries<'a, B, T>
671where
672 B: Borrow<T>,
673 T: ReadTxn,
674{
675 type Item = (&'a str, &'a Item);
676
677 fn next(&mut self) -> Option<Self::Item> {
678 let (mut key, mut ptr) = self.iter.next()?;
679 while ptr.is_deleted() {
680 (key, ptr) = self.iter.next()?;
681 }
682 Some((key, ptr))
683 }
684}
685
686#[derive(Debug, Clone, PartialEq, Eq, Hash)]
688pub(crate) enum TypePtr {
689 Unknown,
693
694 Branch(BranchPtr),
696
697 Named(Arc<str>),
699
700 ID(ID),
702}
703
704impl TypePtr {
705 pub(crate) fn as_branch(&self) -> Option<&BranchPtr> {
706 if let TypePtr::Branch(ptr) = self {
707 Some(ptr)
708 } else {
709 None
710 }
711 }
712}
713
714impl std::fmt::Display for TypePtr {
715 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
716 match self {
717 TypePtr::Unknown => write!(f, "unknown"),
718 TypePtr::Branch(ptr) => {
719 if let Some(i) = ptr.item {
720 write!(f, "{}", i.id())
721 } else {
722 write!(f, "null")
723 }
724 }
725 TypePtr::ID(id) => write!(f, "{}", id),
726 TypePtr::Named(name) => write!(f, "{}", name),
727 }
728 }
729}
730
731pub type Path = VecDeque<PathSegment>;
736
737#[derive(Debug, Clone, PartialEq)]
739pub enum PathSegment {
740 Key(Arc<str>),
742
743 Index(u32),
746}
747
748impl Serialize for PathSegment {
749 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
750 where
751 S: Serializer,
752 {
753 match self {
754 PathSegment::Key(key) => serializer.serialize_str(&*key),
755 PathSegment::Index(i) => serializer.serialize_u32(*i),
756 }
757 }
758}
759
760pub(crate) struct ChangeSet<D> {
761 added: HashSet<ID>,
762 deleted: HashSet<ID>,
763 delta: Vec<D>,
764}
765
766impl<D> ChangeSet<D> {
767 pub fn new(added: HashSet<ID>, deleted: HashSet<ID>, delta: Vec<D>) -> Self {
768 ChangeSet {
769 added,
770 deleted,
771 delta,
772 }
773 }
774}
775
776#[derive(Debug, Clone, PartialEq)]
778pub enum Change {
779 Added(Vec<Out>),
783
784 Removed(u32),
787
788 Retain(u32),
791}
792
793#[derive(Clone, PartialEq)]
795pub enum EntryChange {
796 Inserted(Out),
798
799 Updated(Out, Out),
802
803 Removed(Out),
805}
806
807impl std::fmt::Debug for EntryChange {
808 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
809 match self {
810 EntryChange::Inserted(out) => write!(f, "Inserted({out:?})"),
811 EntryChange::Updated(old, new) => write!(f, "Updated({old:?}, {new:?})"),
812 EntryChange::Removed(out) => {
813 f.write_str("Removed(")?;
814 match out {
816 Out::Any(any) => write!(f, "{any:?}")?,
817 Out::YText(_) => write!(f, "YText")?,
818 Out::YArray(_) => write!(f, "YArray")?,
819 Out::YMap(_) => write!(f, "YMap")?,
820 Out::YXmlElement(_) => write!(f, "YXmlElement")?,
821 Out::YXmlFragment(_) => write!(f, "YXmlFragment")?,
822 Out::YXmlText(_) => write!(f, "YXmlText")?,
823 Out::YDoc(_) => write!(f, "YDoc")?,
824 #[cfg(feature = "weak")]
825 Out::YWeakLink(_) => write!(f, "YWeakLink")?,
826 Out::UndefinedRef(_) => write!(f, "UndefinedRef")?,
827 }
828 f.write_str(")")
829 }
830 }
831 }
832}
833
834#[derive(Debug, Clone, PartialEq)]
836pub enum Delta<T = Out> {
837 Inserted(T, Option<Box<Attrs>>),
840
841 Deleted(u32),
843
844 Retain(u32, Option<Box<Attrs>>),
848}
849
850impl<T> Delta<T> {
851 pub fn map<U, F>(self, f: F) -> Delta<U>
852 where
853 F: FnOnce(T) -> U,
854 {
855 match self {
856 Delta::Inserted(value, attrs) => Delta::Inserted(f(value), attrs),
857 Delta::Deleted(len) => Delta::Deleted(len),
858 Delta::Retain(len, attrs) => Delta::Retain(len, attrs),
859 }
860 }
861}
862
863impl Delta<In> {
864 pub fn retain(len: u32) -> Self {
865 Delta::Retain(len, None)
866 }
867
868 pub fn insert<T: Into<In>>(value: T) -> Self {
869 Delta::Inserted(value.into(), None)
870 }
871
872 pub fn insert_with<T: Into<In>>(value: T, attrs: Attrs) -> Self {
873 Delta::Inserted(value.into(), Some(Box::new(attrs)))
874 }
875
876 pub fn delete(len: u32) -> Self {
877 Delta::Deleted(len)
878 }
879}
880
881pub type Attrs = HashMap<Arc<str>, Any>;
883
884pub(crate) fn event_keys(
885 txn: &TransactionMut,
886 target: BranchPtr,
887 keys_changed: &HashSet<Option<Arc<str>>>,
888) -> HashMap<Arc<str>, EntryChange> {
889 let mut keys = HashMap::new();
890 for opt in keys_changed.iter() {
891 if let Some(key) = opt {
892 let block = target.map.get(key.as_ref()).cloned();
893 if let Some(item) = block.as_deref() {
894 if item.id.clock >= txn.before_state.get(&item.id.client) {
895 let mut prev = item.left;
896 while let Some(p) = prev.as_deref() {
897 if !txn.has_added(&p.id) {
898 break;
899 }
900 prev = p.left;
901 }
902
903 if txn.has_deleted(&item.id) {
904 if let Some(prev) = prev.as_deref() {
905 if txn.has_deleted(&prev.id) {
906 let old_value = prev.content.get_last().unwrap_or_default();
907 keys.insert(key.clone(), EntryChange::Removed(old_value));
908 }
909 }
910 } else {
911 let new_value = item.content.get_last().unwrap();
912 if let Some(prev) = prev.as_deref() {
913 if txn.has_deleted(&prev.id) {
914 let old_value = prev.content.get_last().unwrap_or_default();
915 keys.insert(
916 key.clone(),
917 EntryChange::Updated(old_value, new_value),
918 );
919
920 continue;
921 }
922 }
923
924 keys.insert(key.clone(), EntryChange::Inserted(new_value));
925 }
926 } else if txn.has_deleted(&item.id) {
927 let old_value = item.content.get_last().unwrap_or_default();
928 keys.insert(key.clone(), EntryChange::Removed(old_value));
929 }
930 }
931 }
932 }
933
934 keys
935}
936
937pub(crate) fn event_change_set(txn: &TransactionMut, start: Option<ItemPtr>) -> ChangeSet<Change> {
938 let mut added = HashSet::new();
939 let mut deleted = HashSet::new();
940 let mut delta = Vec::new();
941
942 let mut moved_stack = Vec::new();
943 let mut curr_move: Option<ItemPtr> = None;
944 let mut curr_move_is_new = false;
945 let mut curr_move_is_deleted = false;
946 let mut curr_move_end: Option<ItemPtr> = None;
947 let mut last_op = None;
948
949 #[derive(Default)]
950 struct MoveStackItem {
951 end: Option<ItemPtr>,
952 moved: Option<ItemPtr>,
953 is_new: bool,
954 is_deleted: bool,
955 }
956
957 fn is_moved_by_new(ptr: Option<ItemPtr>, txn: &TransactionMut) -> bool {
958 let mut moved = ptr;
959 while let Some(item) = moved.as_deref() {
960 if txn.has_added(&item.id) {
961 return true;
962 } else {
963 moved = item.moved;
964 }
965 }
966
967 false
968 }
969
970 let encoding = txn.store().offset_kind;
971 let mut current = start;
972 loop {
973 if current == curr_move_end && curr_move.is_some() {
974 current = curr_move;
975 let item: MoveStackItem = moved_stack.pop().unwrap_or_default();
976 curr_move_is_new = item.is_new;
977 curr_move_is_deleted = item.is_deleted;
978 curr_move = item.moved;
979 curr_move_end = item.end;
980 } else {
981 if let Some(item) = current {
982 if let ItemContent::Move(m) = &item.content {
983 if item.moved == curr_move {
984 moved_stack.push(MoveStackItem {
985 end: curr_move_end,
986 moved: curr_move,
987 is_new: curr_move_is_new,
988 is_deleted: curr_move_is_deleted,
989 });
990 let txn = unsafe {
991 (txn as *const TransactionMut as *mut TransactionMut)
994 .as_mut()
995 .unwrap()
996 };
997 let (start, end) = m.get_moved_coords(txn);
998 curr_move = current;
999 curr_move_end = end;
1000 curr_move_is_new = curr_move_is_new || txn.has_added(&item.id);
1001 curr_move_is_deleted = curr_move_is_deleted || item.is_deleted();
1002 current = start;
1003 continue; }
1005 } else if item.moved != curr_move {
1006 if !curr_move_is_new
1007 && item.is_countable()
1008 && (!item.is_deleted() || txn.has_deleted(&item.id))
1009 && !txn.has_added(&item.id)
1010 && (item.moved.is_none()
1011 || curr_move_is_deleted
1012 || is_moved_by_new(item.moved, txn))
1013 && (txn.prev_moved.get(&item).cloned() == curr_move)
1014 {
1015 match item.moved {
1016 Some(ptr) if txn.has_added(ptr.id()) => {
1017 let len = item.content_len(encoding);
1018 last_op = match last_op.take() {
1019 Some(Change::Removed(i)) => Some(Change::Removed(i + len)),
1020 Some(op) => {
1021 delta.push(op);
1022 Some(Change::Removed(len))
1023 }
1024 None => Some(Change::Removed(len)),
1025 };
1026 }
1027 _ => {}
1028 }
1029 }
1030 } else if item.is_deleted() {
1031 if !curr_move_is_new
1032 && txn.has_deleted(&item.id)
1033 && !txn.has_added(&item.id)
1034 && !txn.prev_moved.contains_key(&item)
1035 {
1036 let removed = match last_op.take() {
1037 None => 0,
1038 Some(Change::Removed(c)) => c,
1039 Some(other) => {
1040 delta.push(other);
1041 0
1042 }
1043 };
1044 last_op = Some(Change::Removed(removed + item.len()));
1045 deleted.insert(item.id);
1046 } } else {
1048 if curr_move_is_new
1049 || txn.has_added(&item.id)
1050 || txn.prev_moved.contains_key(&item)
1051 {
1052 let mut inserts = match last_op.take() {
1053 None => Vec::with_capacity(item.len() as usize),
1054 Some(Change::Added(values)) => values,
1055 Some(other) => {
1056 delta.push(other);
1057 Vec::with_capacity(item.len() as usize)
1058 }
1059 };
1060 inserts.append(&mut item.content.get_content());
1061 last_op = Some(Change::Added(inserts));
1062 added.insert(item.id);
1063 } else {
1064 let retain = match last_op.take() {
1065 None => 0,
1066 Some(Change::Retain(c)) => c,
1067 Some(other) => {
1068 delta.push(other);
1069 0
1070 }
1071 };
1072 last_op = Some(Change::Retain(retain + item.len()));
1073 }
1074 }
1075 } else {
1076 break;
1077 }
1078 }
1079
1080 current = if let Some(i) = current.as_deref() {
1081 i.right
1082 } else {
1083 None
1084 };
1085 }
1086
1087 match last_op.take() {
1088 None | Some(Change::Retain(_)) => { }
1089 Some(change) => delta.push(change),
1090 }
1091
1092 ChangeSet::new(added, deleted, delta)
1093}
1094
1095pub struct Events<'a>(Vec<&'a Event>);
1096
1097impl<'a> Events<'a> {
1098 pub(crate) fn new(events: &Vec<&'a Event>) -> Self {
1099 let mut events = events.clone();
1100 events.sort_by(|&a, &b| {
1101 let path1 = a.path();
1102 let path2 = b.path();
1103 path1.len().cmp(&path2.len())
1104 });
1105 Events(events)
1106 }
1107
1108 pub fn iter(&self) -> EventsIter {
1109 EventsIter(self.0.iter())
1110 }
1111}
1112
1113pub struct EventsIter<'a>(std::slice::Iter<'a, &'a Event>);
1114
1115impl<'a> Iterator for EventsIter<'a> {
1116 type Item = &'a Event;
1117
1118 fn next(&mut self) -> Option<Self::Item> {
1119 let e = self.0.next()?;
1120 Some(e)
1121 }
1122
1123 fn size_hint(&self) -> (usize, Option<usize>) {
1124 self.0.size_hint()
1125 }
1126}
1127
1128impl<'a> ExactSizeIterator for EventsIter<'a> {
1129 fn len(&self) -> usize {
1130 self.0.len()
1131 }
1132}
1133
1134pub enum Event {
1136 Text(TextEvent),
1137 Array(ArrayEvent),
1138 Map(MapEvent),
1139 XmlFragment(XmlEvent),
1140 XmlText(XmlTextEvent),
1141 #[cfg(feature = "weak")]
1142 Weak(WeakEvent),
1143}
1144
1145impl AsRef<TextEvent> for Event {
1146 fn as_ref(&self) -> &TextEvent {
1147 if let Event::Text(e) = self {
1148 e
1149 } else {
1150 panic!("subscribed callback expected TextRef collection");
1151 }
1152 }
1153}
1154
1155impl AsRef<ArrayEvent> for Event {
1156 fn as_ref(&self) -> &ArrayEvent {
1157 if let Event::Array(e) = self {
1158 e
1159 } else {
1160 panic!("subscribed callback expected ArrayRef collection");
1161 }
1162 }
1163}
1164
1165impl AsRef<MapEvent> for Event {
1166 fn as_ref(&self) -> &MapEvent {
1167 if let Event::Map(e) = self {
1168 e
1169 } else {
1170 panic!("subscribed callback expected MapRef collection");
1171 }
1172 }
1173}
1174
1175impl AsRef<XmlTextEvent> for Event {
1176 fn as_ref(&self) -> &XmlTextEvent {
1177 if let Event::XmlText(e) = self {
1178 e
1179 } else {
1180 panic!("subscribed callback expected XmlTextRef collection");
1181 }
1182 }
1183}
1184
1185impl AsRef<XmlEvent> for Event {
1186 fn as_ref(&self) -> &XmlEvent {
1187 if let Event::XmlFragment(e) = self {
1188 e
1189 } else {
1190 panic!("subscribed callback expected Xml node");
1191 }
1192 }
1193}
1194
1195#[cfg(feature = "weak")]
1196impl AsRef<WeakEvent> for Event {
1197 fn as_ref(&self) -> &WeakEvent {
1198 if let Event::Weak(e) = self {
1199 e
1200 } else {
1201 panic!("subscribed callback expected WeakRef reference");
1202 }
1203 }
1204}
1205
1206impl Event {
1207 pub(crate) fn set_current_target(&mut self, target: BranchPtr) {
1208 match self {
1209 Event::Text(e) => e.current_target = target,
1210 Event::Array(e) => e.current_target = target,
1211 Event::Map(e) => e.current_target = target,
1212 Event::XmlText(e) => e.current_target = target,
1213 Event::XmlFragment(e) => e.current_target = target,
1214 #[cfg(feature = "weak")]
1215 Event::Weak(e) => e.current_target = target,
1216 }
1217 }
1218
1219 pub fn path(&self) -> Path {
1222 match self {
1223 Event::Text(e) => e.path(),
1224 Event::Array(e) => e.path(),
1225 Event::Map(e) => e.path(),
1226 Event::XmlText(e) => e.path(),
1227 Event::XmlFragment(e) => e.path(),
1228 #[cfg(feature = "weak")]
1229 Event::Weak(e) => e.path(),
1230 }
1231 }
1232
1233 pub fn target(&self) -> Out {
1235 match self {
1236 Event::Text(e) => Out::YText(e.target().clone()),
1237 Event::Array(e) => Out::YArray(e.target().clone()),
1238 Event::Map(e) => Out::YMap(e.target().clone()),
1239 Event::XmlText(e) => Out::YXmlText(e.target().clone()),
1240 Event::XmlFragment(e) => match e.target() {
1241 XmlOut::Element(n) => Out::YXmlElement(n.clone()),
1242 XmlOut::Fragment(n) => Out::YXmlFragment(n.clone()),
1243 XmlOut::Text(n) => Out::YXmlText(n.clone()),
1244 },
1245 #[cfg(feature = "weak")]
1246 Event::Weak(e) => Out::YWeakLink(e.as_target().clone()),
1247 }
1248 }
1249}
1250
1251pub trait ToJson {
1252 fn to_json<T: ReadTxn>(&self, txn: &T) -> Any;
1254}