text.rs

   1mod anchor;
   2pub mod locator;
   3pub mod operation_queue;
   4mod patch;
   5mod point;
   6mod point_utf16;
   7#[cfg(any(test, feature = "test-support"))]
   8pub mod random_char_iter;
   9pub mod rope;
  10mod selection;
  11pub mod subscription;
  12#[cfg(test)]
  13mod tests;
  14
  15pub use anchor::*;
  16use anyhow::Result;
  17use clock::ReplicaId;
  18use collections::{HashMap, HashSet};
  19use locator::Locator;
  20use operation_queue::OperationQueue;
  21pub use patch::Patch;
  22pub use point::*;
  23pub use point_utf16::*;
  24#[cfg(any(test, feature = "test-support"))]
  25pub use random_char_iter::*;
  26use rope::TextDimension;
  27pub use rope::{Chunks, Rope, TextSummary};
  28pub use selection::*;
  29use std::{
  30    cmp::{self, Ordering},
  31    iter::Iterator,
  32    ops::{self, Deref, Range, Sub},
  33    str,
  34    sync::Arc,
  35    time::{Duration, Instant},
  36};
  37pub use subscription::*;
  38pub use sum_tree::Bias;
  39use sum_tree::{FilterCursor, SumTree};
  40
  41pub type TransactionId = usize;
  42
  43pub struct Buffer {
  44    snapshot: BufferSnapshot,
  45    history: History,
  46    deferred_ops: OperationQueue<Operation>,
  47    deferred_replicas: HashSet<ReplicaId>,
  48    replica_id: ReplicaId,
  49    remote_id: u64,
  50    local_clock: clock::Local,
  51    pub lamport_clock: clock::Lamport,
  52    subscriptions: Topic,
  53}
  54
  55#[derive(Clone, Debug)]
  56pub struct BufferSnapshot {
  57    replica_id: ReplicaId,
  58    visible_text: Rope,
  59    deleted_text: Rope,
  60    undo_map: UndoMap,
  61    fragments: SumTree<Fragment>,
  62    insertions: SumTree<InsertionFragment>,
  63    pub version: clock::Global,
  64}
  65
  66#[derive(Clone, Debug)]
  67pub struct Transaction {
  68    id: TransactionId,
  69    start: clock::Global,
  70    end: clock::Global,
  71    edits: Vec<clock::Local>,
  72    ranges: Vec<Range<FullOffset>>,
  73    first_edit_at: Instant,
  74    last_edit_at: Instant,
  75}
  76
  77impl Transaction {
  78    fn push_edit(&mut self, edit: &EditOperation) {
  79        self.edits.push(edit.timestamp.local());
  80        self.end.observe(edit.timestamp.local());
  81
  82        let mut other_ranges = edit.ranges.iter().peekable();
  83        let mut new_ranges = Vec::new();
  84        let insertion_len = edit.new_text.as_ref().map_or(0, |t| t.len());
  85        let mut delta = 0;
  86
  87        for mut self_range in self.ranges.iter().cloned() {
  88            self_range.start += delta;
  89            self_range.end += delta;
  90
  91            while let Some(other_range) = other_ranges.peek() {
  92                let mut other_range = (*other_range).clone();
  93                other_range.start += delta;
  94                other_range.end += delta;
  95
  96                if other_range.start <= self_range.end {
  97                    other_ranges.next().unwrap();
  98                    delta += insertion_len;
  99
 100                    if other_range.end < self_range.start {
 101                        new_ranges.push(other_range.start..other_range.end + insertion_len);
 102                        self_range.start += insertion_len;
 103                        self_range.end += insertion_len;
 104                    } else {
 105                        self_range.start = cmp::min(self_range.start, other_range.start);
 106                        self_range.end = cmp::max(self_range.end, other_range.end) + insertion_len;
 107                    }
 108                } else {
 109                    break;
 110                }
 111            }
 112
 113            new_ranges.push(self_range);
 114        }
 115
 116        for other_range in other_ranges {
 117            new_ranges.push(other_range.start + delta..other_range.end + delta + insertion_len);
 118            delta += insertion_len;
 119        }
 120
 121        self.ranges = new_ranges;
 122    }
 123}
 124
 125#[derive(Clone)]
 126pub struct History {
 127    // TODO: Turn this into a String or Rope, maybe.
 128    pub base_text: Arc<str>,
 129    ops: HashMap<clock::Local, EditOperation>,
 130    undo_stack: Vec<Transaction>,
 131    redo_stack: Vec<Transaction>,
 132    transaction_depth: usize,
 133    group_interval: Duration,
 134    next_transaction_id: TransactionId,
 135}
 136
 137impl History {
 138    pub fn new(base_text: Arc<str>) -> Self {
 139        Self {
 140            base_text,
 141            ops: Default::default(),
 142            undo_stack: Vec::new(),
 143            redo_stack: Vec::new(),
 144            transaction_depth: 0,
 145            group_interval: Duration::from_millis(300),
 146            next_transaction_id: 0,
 147        }
 148    }
 149
 150    fn push(&mut self, op: EditOperation) {
 151        self.ops.insert(op.timestamp.local(), op);
 152    }
 153
 154    fn start_transaction(&mut self, start: clock::Global, now: Instant) -> Option<TransactionId> {
 155        self.transaction_depth += 1;
 156        if self.transaction_depth == 1 {
 157            let id = self.next_transaction_id;
 158            self.next_transaction_id += 1;
 159            self.undo_stack.push(Transaction {
 160                id,
 161                start: start.clone(),
 162                end: start,
 163                edits: Vec::new(),
 164                ranges: Vec::new(),
 165                first_edit_at: now,
 166                last_edit_at: now,
 167            });
 168            Some(id)
 169        } else {
 170            None
 171        }
 172    }
 173
 174    fn end_transaction(&mut self, now: Instant) -> Option<&Transaction> {
 175        assert_ne!(self.transaction_depth, 0);
 176        self.transaction_depth -= 1;
 177        if self.transaction_depth == 0 {
 178            if self.undo_stack.last().unwrap().ranges.is_empty() {
 179                self.undo_stack.pop();
 180                None
 181            } else {
 182                let transaction = self.undo_stack.last_mut().unwrap();
 183                transaction.last_edit_at = now;
 184                Some(transaction)
 185            }
 186        } else {
 187            None
 188        }
 189    }
 190
 191    fn group(&mut self) -> Option<TransactionId> {
 192        let mut new_len = self.undo_stack.len();
 193        let mut transactions = self.undo_stack.iter_mut();
 194
 195        if let Some(mut transaction) = transactions.next_back() {
 196            while let Some(prev_transaction) = transactions.next_back() {
 197                if transaction.first_edit_at - prev_transaction.last_edit_at <= self.group_interval
 198                    && transaction.start == prev_transaction.end
 199                {
 200                    transaction = prev_transaction;
 201                    new_len -= 1;
 202                } else {
 203                    break;
 204                }
 205            }
 206        }
 207
 208        let (transactions_to_keep, transactions_to_merge) = self.undo_stack.split_at_mut(new_len);
 209        if let Some(last_transaction) = transactions_to_keep.last_mut() {
 210            for transaction in &*transactions_to_merge {
 211                for edit_id in &transaction.edits {
 212                    last_transaction.push_edit(&self.ops[edit_id]);
 213                }
 214            }
 215
 216            if let Some(transaction) = transactions_to_merge.last_mut() {
 217                last_transaction.last_edit_at = transaction.last_edit_at;
 218                last_transaction.end = transaction.end.clone();
 219            }
 220        }
 221
 222        self.undo_stack.truncate(new_len);
 223        self.undo_stack.last().map(|t| t.id)
 224    }
 225
 226    fn push_undo(&mut self, edit_id: clock::Local) {
 227        assert_ne!(self.transaction_depth, 0);
 228        let last_transaction = self.undo_stack.last_mut().unwrap();
 229        last_transaction.push_edit(&self.ops[&edit_id]);
 230    }
 231
 232    fn pop_undo(&mut self) -> Option<&Transaction> {
 233        assert_eq!(self.transaction_depth, 0);
 234        if let Some(transaction) = self.undo_stack.pop() {
 235            self.redo_stack.push(transaction);
 236            self.redo_stack.last()
 237        } else {
 238            None
 239        }
 240    }
 241
 242    fn remove_from_undo(&mut self, transaction_id: TransactionId) -> Option<&Transaction> {
 243        assert_eq!(self.transaction_depth, 0);
 244        if let Some(transaction_ix) = self.undo_stack.iter().rposition(|t| t.id == transaction_id) {
 245            let transaction = self.undo_stack.remove(transaction_ix);
 246            self.redo_stack.push(transaction);
 247            self.redo_stack.last()
 248        } else {
 249            None
 250        }
 251    }
 252
 253    fn pop_redo(&mut self) -> Option<&Transaction> {
 254        assert_eq!(self.transaction_depth, 0);
 255        if let Some(transaction) = self.redo_stack.pop() {
 256            self.undo_stack.push(transaction);
 257            self.undo_stack.last()
 258        } else {
 259            None
 260        }
 261    }
 262
 263    fn remove_from_redo(&mut self, transaction_id: TransactionId) -> Option<&Transaction> {
 264        assert_eq!(self.transaction_depth, 0);
 265        if let Some(transaction_ix) = self.redo_stack.iter().rposition(|t| t.id == transaction_id) {
 266            let transaction = self.redo_stack.remove(transaction_ix);
 267            self.undo_stack.push(transaction);
 268            self.undo_stack.last()
 269        } else {
 270            None
 271        }
 272    }
 273}
 274
 275#[derive(Clone, Default, Debug)]
 276struct UndoMap(HashMap<clock::Local, Vec<(clock::Local, u32)>>);
 277
 278impl UndoMap {
 279    fn insert(&mut self, undo: &UndoOperation) {
 280        for (edit_id, count) in &undo.counts {
 281            self.0.entry(*edit_id).or_default().push((undo.id, *count));
 282        }
 283    }
 284
 285    fn is_undone(&self, edit_id: clock::Local) -> bool {
 286        self.undo_count(edit_id) % 2 == 1
 287    }
 288
 289    fn was_undone(&self, edit_id: clock::Local, version: &clock::Global) -> bool {
 290        let undo_count = self
 291            .0
 292            .get(&edit_id)
 293            .unwrap_or(&Vec::new())
 294            .iter()
 295            .filter(|(undo_id, _)| version.observed(*undo_id))
 296            .map(|(_, undo_count)| *undo_count)
 297            .max()
 298            .unwrap_or(0);
 299        undo_count % 2 == 1
 300    }
 301
 302    fn undo_count(&self, edit_id: clock::Local) -> u32 {
 303        self.0
 304            .get(&edit_id)
 305            .unwrap_or(&Vec::new())
 306            .iter()
 307            .map(|(_, undo_count)| *undo_count)
 308            .max()
 309            .unwrap_or(0)
 310    }
 311}
 312
 313struct Edits<'a, D: TextDimension, F: FnMut(&FragmentSummary) -> bool> {
 314    visible_cursor: rope::Cursor<'a>,
 315    deleted_cursor: rope::Cursor<'a>,
 316    fragments_cursor: Option<FilterCursor<'a, F, Fragment, FragmentTextSummary>>,
 317    undos: &'a UndoMap,
 318    since: &'a clock::Global,
 319    old_end: D,
 320    new_end: D,
 321    range: Range<(&'a Locator, usize)>,
 322}
 323
 324#[derive(Clone, Debug, Default, Eq, PartialEq)]
 325pub struct Edit<D> {
 326    pub old: Range<D>,
 327    pub new: Range<D>,
 328}
 329
 330impl<D> Edit<D>
 331where
 332    D: Sub<D, Output = D> + PartialEq + Copy,
 333{
 334    pub fn old_len(&self) -> D {
 335        self.old.end - self.old.start
 336    }
 337
 338    pub fn new_len(&self) -> D {
 339        self.new.end - self.new.start
 340    }
 341
 342    pub fn is_empty(&self) -> bool {
 343        self.old.start == self.old.end && self.new.start == self.new.end
 344    }
 345}
 346
 347impl<D1, D2> Edit<(D1, D2)> {
 348    pub fn flatten(self) -> (Edit<D1>, Edit<D2>) {
 349        (
 350            Edit {
 351                old: self.old.start.0..self.old.end.0,
 352                new: self.new.start.0..self.new.end.0,
 353            },
 354            Edit {
 355                old: self.old.start.1..self.old.end.1,
 356                new: self.new.start.1..self.new.end.1,
 357            },
 358        )
 359    }
 360}
 361
 362#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
 363pub struct InsertionTimestamp {
 364    pub replica_id: ReplicaId,
 365    pub local: clock::Seq,
 366    pub lamport: clock::Seq,
 367}
 368
 369impl InsertionTimestamp {
 370    fn local(&self) -> clock::Local {
 371        clock::Local {
 372            replica_id: self.replica_id,
 373            value: self.local,
 374        }
 375    }
 376
 377    fn lamport(&self) -> clock::Lamport {
 378        clock::Lamport {
 379            replica_id: self.replica_id,
 380            value: self.lamport,
 381        }
 382    }
 383}
 384
 385#[derive(Eq, PartialEq, Clone, Debug)]
 386pub struct Fragment {
 387    pub id: Locator,
 388    pub insertion_timestamp: InsertionTimestamp,
 389    pub insertion_offset: usize,
 390    pub len: usize,
 391    pub visible: bool,
 392    pub deletions: HashSet<clock::Local>,
 393    pub max_undos: clock::Global,
 394}
 395
 396#[derive(Eq, PartialEq, Clone, Debug)]
 397pub struct FragmentSummary {
 398    text: FragmentTextSummary,
 399    max_id: Locator,
 400    max_version: clock::Global,
 401    min_insertion_version: clock::Global,
 402    max_insertion_version: clock::Global,
 403}
 404
 405#[derive(Copy, Default, Clone, Debug, PartialEq, Eq)]
 406struct FragmentTextSummary {
 407    visible: usize,
 408    deleted: usize,
 409}
 410
 411impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary {
 412    fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
 413        self.visible += summary.text.visible;
 414        self.deleted += summary.text.deleted;
 415    }
 416}
 417
 418#[derive(Eq, PartialEq, Clone, Debug)]
 419struct InsertionFragment {
 420    timestamp: clock::Local,
 421    split_offset: usize,
 422    fragment_id: Locator,
 423}
 424
 425#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
 426struct InsertionFragmentKey {
 427    timestamp: clock::Local,
 428    split_offset: usize,
 429}
 430
 431#[derive(Clone, Debug, Eq, PartialEq)]
 432pub enum Operation {
 433    Edit(EditOperation),
 434    Undo {
 435        undo: UndoOperation,
 436        lamport_timestamp: clock::Lamport,
 437    },
 438}
 439
 440#[derive(Clone, Debug, Eq, PartialEq)]
 441pub struct EditOperation {
 442    pub timestamp: InsertionTimestamp,
 443    pub version: clock::Global,
 444    pub ranges: Vec<Range<FullOffset>>,
 445    pub new_text: Option<String>,
 446}
 447
 448#[derive(Clone, Debug, Eq, PartialEq)]
 449pub struct UndoOperation {
 450    pub id: clock::Local,
 451    pub counts: HashMap<clock::Local, u32>,
 452    pub ranges: Vec<Range<FullOffset>>,
 453    pub version: clock::Global,
 454}
 455
 456impl Buffer {
 457    pub fn new(replica_id: u16, remote_id: u64, history: History) -> Buffer {
 458        let mut fragments = SumTree::new();
 459        let mut insertions = SumTree::new();
 460
 461        let mut local_clock = clock::Local::new(replica_id);
 462        let mut lamport_clock = clock::Lamport::new(replica_id);
 463        let mut version = clock::Global::new();
 464        let visible_text = Rope::from(history.base_text.as_ref());
 465        if visible_text.len() > 0 {
 466            let insertion_timestamp = InsertionTimestamp {
 467                replica_id: 0,
 468                local: 1,
 469                lamport: 1,
 470            };
 471            local_clock.observe(insertion_timestamp.local());
 472            lamport_clock.observe(insertion_timestamp.lamport());
 473            version.observe(insertion_timestamp.local());
 474            let fragment_id = Locator::between(&Locator::min(), &Locator::max());
 475            let fragment = Fragment {
 476                id: fragment_id,
 477                insertion_timestamp,
 478                insertion_offset: 0,
 479                len: visible_text.len(),
 480                visible: true,
 481                deletions: Default::default(),
 482                max_undos: Default::default(),
 483            };
 484            insertions.push(InsertionFragment::new(&fragment), &());
 485            fragments.push(fragment, &None);
 486        }
 487
 488        Buffer {
 489            snapshot: BufferSnapshot {
 490                replica_id,
 491                visible_text,
 492                deleted_text: Rope::new(),
 493                fragments,
 494                insertions,
 495                version,
 496                undo_map: Default::default(),
 497            },
 498            history,
 499            deferred_ops: OperationQueue::new(),
 500            deferred_replicas: HashSet::default(),
 501            replica_id,
 502            remote_id,
 503            local_clock,
 504            lamport_clock,
 505            subscriptions: Default::default(),
 506        }
 507    }
 508
 509    pub fn from_parts(
 510        replica_id: u16,
 511        remote_id: u64,
 512        visible_text: &str,
 513        deleted_text: &str,
 514        undo_map: impl Iterator<Item = (clock::Local, Vec<(clock::Local, u32)>)>,
 515        fragments: impl ExactSizeIterator<Item = Fragment>,
 516        lamport_timestamp: u32,
 517        version: clock::Global,
 518    ) -> Self {
 519        let visible_text = visible_text.into();
 520        let deleted_text = deleted_text.into();
 521        let fragments = SumTree::from_iter(fragments, &None);
 522        let mut insertions = fragments
 523            .iter()
 524            .map(|fragment| InsertionFragment {
 525                timestamp: fragment.insertion_timestamp.local(),
 526                split_offset: fragment.insertion_offset,
 527                fragment_id: fragment.id.clone(),
 528            })
 529            .collect::<Vec<_>>();
 530        insertions.sort_unstable_by_key(|i| (i.timestamp, i.split_offset));
 531        Self {
 532            remote_id,
 533            replica_id,
 534
 535            history: History::new("".into()),
 536            deferred_ops: OperationQueue::new(),
 537            deferred_replicas: Default::default(),
 538            local_clock: clock::Local {
 539                replica_id,
 540                value: version.get(replica_id) + 1,
 541            },
 542            lamport_clock: clock::Lamport {
 543                replica_id,
 544                value: lamport_timestamp,
 545            },
 546            subscriptions: Default::default(),
 547            snapshot: BufferSnapshot {
 548                replica_id,
 549                visible_text,
 550                deleted_text,
 551                undo_map: UndoMap(undo_map.collect()),
 552                fragments,
 553                insertions: SumTree::from_iter(insertions, &()),
 554                version,
 555            },
 556        }
 557    }
 558
 559    pub fn version(&self) -> clock::Global {
 560        self.version.clone()
 561    }
 562
 563    pub fn snapshot(&self) -> BufferSnapshot {
 564        self.snapshot.clone()
 565    }
 566
 567    pub fn replica_id(&self) -> ReplicaId {
 568        self.local_clock.replica_id
 569    }
 570
 571    pub fn remote_id(&self) -> u64 {
 572        self.remote_id
 573    }
 574
 575    pub fn deferred_ops_len(&self) -> usize {
 576        self.deferred_ops.len()
 577    }
 578
 579    pub fn transaction_group_interval(&self) -> Duration {
 580        self.history.group_interval
 581    }
 582
 583    pub fn edit<R, I, S, T>(&mut self, ranges: R, new_text: T) -> EditOperation
 584    where
 585        R: IntoIterator<IntoIter = I>,
 586        I: ExactSizeIterator<Item = Range<S>>,
 587        S: ToOffset,
 588        T: Into<String>,
 589    {
 590        let new_text = new_text.into();
 591        let new_text_len = new_text.len();
 592        let new_text = if new_text_len > 0 {
 593            Some(new_text)
 594        } else {
 595            None
 596        };
 597
 598        self.start_transaction();
 599        let timestamp = InsertionTimestamp {
 600            replica_id: self.replica_id,
 601            local: self.local_clock.tick().value,
 602            lamport: self.lamport_clock.tick().value,
 603        };
 604        let edit = self.apply_local_edit(ranges.into_iter(), new_text, timestamp);
 605
 606        self.history.push(edit.clone());
 607        self.history.push_undo(edit.timestamp.local());
 608        self.snapshot.version.observe(edit.timestamp.local());
 609        self.end_transaction();
 610        edit
 611    }
 612
 613    fn apply_local_edit<S: ToOffset>(
 614        &mut self,
 615        ranges: impl ExactSizeIterator<Item = Range<S>>,
 616        new_text: Option<String>,
 617        timestamp: InsertionTimestamp,
 618    ) -> EditOperation {
 619        let mut edits = Patch::default();
 620        let mut edit_op = EditOperation {
 621            timestamp,
 622            version: self.version(),
 623            ranges: Vec::with_capacity(ranges.len()),
 624            new_text: None,
 625        };
 626        let mut new_insertions = Vec::new();
 627        let mut insertion_offset = 0;
 628
 629        let mut ranges = ranges
 630            .map(|range| range.start.to_offset(&*self)..range.end.to_offset(&*self))
 631            .peekable();
 632
 633        let mut new_ropes =
 634            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
 635        let mut old_fragments = self.fragments.cursor::<FragmentTextSummary>();
 636        let mut new_fragments =
 637            old_fragments.slice(&ranges.peek().unwrap().start, Bias::Right, &None);
 638        new_ropes.push_tree(new_fragments.summary().text);
 639
 640        let mut fragment_start = old_fragments.start().visible;
 641        for range in ranges {
 642            let fragment_end = old_fragments.end(&None).visible;
 643
 644            // If the current fragment ends before this range, then jump ahead to the first fragment
 645            // that extends past the start of this range, reusing any intervening fragments.
 646            if fragment_end < range.start {
 647                // If the current fragment has been partially consumed, then consume the rest of it
 648                // and advance to the next fragment before slicing.
 649                if fragment_start > old_fragments.start().visible {
 650                    if fragment_end > fragment_start {
 651                        let mut suffix = old_fragments.item().unwrap().clone();
 652                        suffix.len = fragment_end - fragment_start;
 653                        suffix.insertion_offset += fragment_start - old_fragments.start().visible;
 654                        new_insertions.push(InsertionFragment::insert_new(&suffix));
 655                        new_ropes.push_fragment(&suffix, suffix.visible);
 656                        new_fragments.push(suffix, &None);
 657                    }
 658                    old_fragments.next(&None);
 659                }
 660
 661                let slice = old_fragments.slice(&range.start, Bias::Right, &None);
 662                new_ropes.push_tree(slice.summary().text);
 663                new_fragments.push_tree(slice, &None);
 664                fragment_start = old_fragments.start().visible;
 665            }
 666
 667            let full_range_start = FullOffset(range.start + old_fragments.start().deleted);
 668
 669            // Preserve any portion of the current fragment that precedes this range.
 670            if fragment_start < range.start {
 671                let mut prefix = old_fragments.item().unwrap().clone();
 672                prefix.len = range.start - fragment_start;
 673                prefix.insertion_offset += fragment_start - old_fragments.start().visible;
 674                prefix.id = Locator::between(&new_fragments.summary().max_id, &prefix.id);
 675                new_insertions.push(InsertionFragment::insert_new(&prefix));
 676                new_ropes.push_fragment(&prefix, prefix.visible);
 677                new_fragments.push(prefix, &None);
 678                fragment_start = range.start;
 679            }
 680
 681            // Insert the new text before any existing fragments within the range.
 682            if let Some(new_text) = new_text.as_deref() {
 683                let new_start = new_fragments.summary().text.visible;
 684                edits.push(Edit {
 685                    old: fragment_start..fragment_start,
 686                    new: new_start..new_start + new_text.len(),
 687                });
 688                let fragment = Fragment {
 689                    id: Locator::between(
 690                        &new_fragments.summary().max_id,
 691                        old_fragments
 692                            .item()
 693                            .map_or(&Locator::max(), |old_fragment| &old_fragment.id),
 694                    ),
 695                    insertion_timestamp: timestamp,
 696                    insertion_offset,
 697                    len: new_text.len(),
 698                    deletions: Default::default(),
 699                    max_undos: Default::default(),
 700                    visible: true,
 701                };
 702                new_insertions.push(InsertionFragment::insert_new(&fragment));
 703                new_ropes.push_str(new_text);
 704                new_fragments.push(fragment, &None);
 705                insertion_offset += new_text.len();
 706            }
 707
 708            // Advance through every fragment that intersects this range, marking the intersecting
 709            // portions as deleted.
 710            while fragment_start < range.end {
 711                let fragment = old_fragments.item().unwrap();
 712                let fragment_end = old_fragments.end(&None).visible;
 713                let mut intersection = fragment.clone();
 714                let intersection_end = cmp::min(range.end, fragment_end);
 715                if fragment.visible {
 716                    intersection.len = intersection_end - fragment_start;
 717                    intersection.insertion_offset += fragment_start - old_fragments.start().visible;
 718                    intersection.id =
 719                        Locator::between(&new_fragments.summary().max_id, &intersection.id);
 720                    intersection.deletions.insert(timestamp.local());
 721                    intersection.visible = false;
 722                }
 723                if intersection.len > 0 {
 724                    if fragment.visible && !intersection.visible {
 725                        let new_start = new_fragments.summary().text.visible;
 726                        edits.push(Edit {
 727                            old: fragment_start..intersection_end,
 728                            new: new_start..new_start,
 729                        });
 730                    }
 731                    new_insertions.push(InsertionFragment::insert_new(&intersection));
 732                    new_ropes.push_fragment(&intersection, fragment.visible);
 733                    new_fragments.push(intersection, &None);
 734                    fragment_start = intersection_end;
 735                }
 736                if fragment_end <= range.end {
 737                    old_fragments.next(&None);
 738                }
 739            }
 740
 741            let full_range_end = FullOffset(range.end + old_fragments.start().deleted);
 742            edit_op.ranges.push(full_range_start..full_range_end);
 743        }
 744
 745        // If the current fragment has been partially consumed, then consume the rest of it
 746        // and advance to the next fragment before slicing.
 747        if fragment_start > old_fragments.start().visible {
 748            let fragment_end = old_fragments.end(&None).visible;
 749            if fragment_end > fragment_start {
 750                let mut suffix = old_fragments.item().unwrap().clone();
 751                suffix.len = fragment_end - fragment_start;
 752                suffix.insertion_offset += fragment_start - old_fragments.start().visible;
 753                new_insertions.push(InsertionFragment::insert_new(&suffix));
 754                new_ropes.push_fragment(&suffix, suffix.visible);
 755                new_fragments.push(suffix, &None);
 756            }
 757            old_fragments.next(&None);
 758        }
 759
 760        let suffix = old_fragments.suffix(&None);
 761        new_ropes.push_tree(suffix.summary().text);
 762        new_fragments.push_tree(suffix, &None);
 763        let (visible_text, deleted_text) = new_ropes.finish();
 764        drop(old_fragments);
 765
 766        self.snapshot.fragments = new_fragments;
 767        self.snapshot.insertions.edit(new_insertions, &());
 768        self.snapshot.visible_text = visible_text;
 769        self.snapshot.deleted_text = deleted_text;
 770        self.subscriptions.publish_mut(&edits);
 771        edit_op.new_text = new_text;
 772        edit_op
 773    }
 774
 775    pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I) -> Result<()> {
 776        let mut deferred_ops = Vec::new();
 777        for op in ops {
 778            if self.can_apply_op(&op) {
 779                self.apply_op(op)?;
 780            } else {
 781                self.deferred_replicas.insert(op.replica_id());
 782                deferred_ops.push(op);
 783            }
 784        }
 785        self.deferred_ops.insert(deferred_ops);
 786        self.flush_deferred_ops()?;
 787        Ok(())
 788    }
 789
 790    fn apply_op(&mut self, op: Operation) -> Result<()> {
 791        match op {
 792            Operation::Edit(edit) => {
 793                if !self.version.observed(edit.timestamp.local()) {
 794                    self.apply_remote_edit(
 795                        &edit.version,
 796                        &edit.ranges,
 797                        edit.new_text.as_deref(),
 798                        edit.timestamp,
 799                    );
 800                    self.snapshot.version.observe(edit.timestamp.local());
 801                    self.history.push(edit);
 802                }
 803            }
 804            Operation::Undo {
 805                undo,
 806                lamport_timestamp,
 807            } => {
 808                if !self.version.observed(undo.id) {
 809                    self.apply_undo(&undo)?;
 810                    self.snapshot.version.observe(undo.id);
 811                    self.lamport_clock.observe(lamport_timestamp);
 812                }
 813            }
 814        }
 815        Ok(())
 816    }
 817
 818    fn apply_remote_edit(
 819        &mut self,
 820        version: &clock::Global,
 821        ranges: &[Range<FullOffset>],
 822        new_text: Option<&str>,
 823        timestamp: InsertionTimestamp,
 824    ) {
 825        if ranges.is_empty() {
 826            return;
 827        }
 828
 829        let mut edits = Patch::default();
 830        let cx = Some(version.clone());
 831        let mut new_insertions = Vec::new();
 832        let mut insertion_offset = 0;
 833        let mut new_ropes =
 834            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
 835        let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>();
 836        let mut new_fragments = old_fragments.slice(
 837            &VersionedFullOffset::Offset(ranges[0].start),
 838            Bias::Left,
 839            &cx,
 840        );
 841        new_ropes.push_tree(new_fragments.summary().text);
 842
 843        let mut fragment_start = old_fragments.start().0.full_offset();
 844        for range in ranges {
 845            let fragment_end = old_fragments.end(&cx).0.full_offset();
 846
 847            // If the current fragment ends before this range, then jump ahead to the first fragment
 848            // that extends past the start of this range, reusing any intervening fragments.
 849            if fragment_end < range.start {
 850                // If the current fragment has been partially consumed, then consume the rest of it
 851                // and advance to the next fragment before slicing.
 852                if fragment_start > old_fragments.start().0.full_offset() {
 853                    if fragment_end > fragment_start {
 854                        let mut suffix = old_fragments.item().unwrap().clone();
 855                        suffix.len = fragment_end.0 - fragment_start.0;
 856                        suffix.insertion_offset +=
 857                            fragment_start - old_fragments.start().0.full_offset();
 858                        new_insertions.push(InsertionFragment::insert_new(&suffix));
 859                        new_ropes.push_fragment(&suffix, suffix.visible);
 860                        new_fragments.push(suffix, &None);
 861                    }
 862                    old_fragments.next(&cx);
 863                }
 864
 865                let slice =
 866                    old_fragments.slice(&VersionedFullOffset::Offset(range.start), Bias::Left, &cx);
 867                new_ropes.push_tree(slice.summary().text);
 868                new_fragments.push_tree(slice, &None);
 869                fragment_start = old_fragments.start().0.full_offset();
 870            }
 871
 872            // If we are at the end of a non-concurrent fragment, advance to the next one.
 873            let fragment_end = old_fragments.end(&cx).0.full_offset();
 874            if fragment_end == range.start && fragment_end > fragment_start {
 875                let mut fragment = old_fragments.item().unwrap().clone();
 876                fragment.len = fragment_end.0 - fragment_start.0;
 877                fragment.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
 878                new_insertions.push(InsertionFragment::insert_new(&fragment));
 879                new_ropes.push_fragment(&fragment, fragment.visible);
 880                new_fragments.push(fragment, &None);
 881                old_fragments.next(&cx);
 882                fragment_start = old_fragments.start().0.full_offset();
 883            }
 884
 885            // Skip over insertions that are concurrent to this edit, but have a lower lamport
 886            // timestamp.
 887            while let Some(fragment) = old_fragments.item() {
 888                if fragment_start == range.start
 889                    && fragment.insertion_timestamp.lamport() > timestamp.lamport()
 890                {
 891                    new_ropes.push_fragment(fragment, fragment.visible);
 892                    new_fragments.push(fragment.clone(), &None);
 893                    old_fragments.next(&cx);
 894                    debug_assert_eq!(fragment_start, range.start);
 895                } else {
 896                    break;
 897                }
 898            }
 899            debug_assert!(fragment_start <= range.start);
 900
 901            // Preserve any portion of the current fragment that precedes this range.
 902            if fragment_start < range.start {
 903                let mut prefix = old_fragments.item().unwrap().clone();
 904                prefix.len = range.start.0 - fragment_start.0;
 905                prefix.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
 906                prefix.id = Locator::between(&new_fragments.summary().max_id, &prefix.id);
 907                new_insertions.push(InsertionFragment::insert_new(&prefix));
 908                fragment_start = range.start;
 909                new_ropes.push_fragment(&prefix, prefix.visible);
 910                new_fragments.push(prefix, &None);
 911            }
 912
 913            // Insert the new text before any existing fragments within the range.
 914            if let Some(new_text) = new_text {
 915                let mut old_start = old_fragments.start().1;
 916                if old_fragments.item().map_or(false, |f| f.visible) {
 917                    old_start += fragment_start.0 - old_fragments.start().0.full_offset().0;
 918                }
 919                let new_start = new_fragments.summary().text.visible;
 920                edits.push(Edit {
 921                    old: old_start..old_start,
 922                    new: new_start..new_start + new_text.len(),
 923                });
 924                let fragment = Fragment {
 925                    id: Locator::between(
 926                        &new_fragments.summary().max_id,
 927                        old_fragments
 928                            .item()
 929                            .map_or(&Locator::max(), |old_fragment| &old_fragment.id),
 930                    ),
 931                    insertion_timestamp: timestamp,
 932                    insertion_offset,
 933                    len: new_text.len(),
 934                    deletions: Default::default(),
 935                    max_undos: Default::default(),
 936                    visible: true,
 937                };
 938                new_insertions.push(InsertionFragment::insert_new(&fragment));
 939                new_ropes.push_str(new_text);
 940                new_fragments.push(fragment, &None);
 941                insertion_offset += new_text.len();
 942            }
 943
 944            // Advance through every fragment that intersects this range, marking the intersecting
 945            // portions as deleted.
 946            while fragment_start < range.end {
 947                let fragment = old_fragments.item().unwrap();
 948                let fragment_end = old_fragments.end(&cx).0.full_offset();
 949                let mut intersection = fragment.clone();
 950                let intersection_end = cmp::min(range.end, fragment_end);
 951                if fragment.was_visible(version, &self.undo_map) {
 952                    intersection.len = intersection_end.0 - fragment_start.0;
 953                    intersection.insertion_offset +=
 954                        fragment_start - old_fragments.start().0.full_offset();
 955                    intersection.id =
 956                        Locator::between(&new_fragments.summary().max_id, &intersection.id);
 957                    intersection.deletions.insert(timestamp.local());
 958                    intersection.visible = false;
 959                }
 960                if intersection.len > 0 {
 961                    if fragment.visible && !intersection.visible {
 962                        let old_start = old_fragments.start().1
 963                            + (fragment_start.0 - old_fragments.start().0.full_offset().0);
 964                        let new_start = new_fragments.summary().text.visible;
 965                        edits.push(Edit {
 966                            old: old_start..old_start + intersection.len,
 967                            new: new_start..new_start,
 968                        });
 969                    }
 970                    new_insertions.push(InsertionFragment::insert_new(&intersection));
 971                    new_ropes.push_fragment(&intersection, fragment.visible);
 972                    new_fragments.push(intersection, &None);
 973                    fragment_start = intersection_end;
 974                }
 975                if fragment_end <= range.end {
 976                    old_fragments.next(&cx);
 977                }
 978            }
 979        }
 980
 981        // If the current fragment has been partially consumed, then consume the rest of it
 982        // and advance to the next fragment before slicing.
 983        if fragment_start > old_fragments.start().0.full_offset() {
 984            let fragment_end = old_fragments.end(&cx).0.full_offset();
 985            if fragment_end > fragment_start {
 986                let mut suffix = old_fragments.item().unwrap().clone();
 987                suffix.len = fragment_end.0 - fragment_start.0;
 988                suffix.insertion_offset += fragment_start - old_fragments.start().0.full_offset();
 989                new_insertions.push(InsertionFragment::insert_new(&suffix));
 990                new_ropes.push_fragment(&suffix, suffix.visible);
 991                new_fragments.push(suffix, &None);
 992            }
 993            old_fragments.next(&cx);
 994        }
 995
 996        let suffix = old_fragments.suffix(&cx);
 997        new_ropes.push_tree(suffix.summary().text);
 998        new_fragments.push_tree(suffix, &None);
 999        let (visible_text, deleted_text) = new_ropes.finish();
1000        drop(old_fragments);
1001
1002        self.snapshot.fragments = new_fragments;
1003        self.snapshot.visible_text = visible_text;
1004        self.snapshot.deleted_text = deleted_text;
1005        self.snapshot.insertions.edit(new_insertions, &());
1006        self.local_clock.observe(timestamp.local());
1007        self.lamport_clock.observe(timestamp.lamport());
1008        self.subscriptions.publish_mut(&edits);
1009    }
1010
1011    fn apply_undo(&mut self, undo: &UndoOperation) -> Result<()> {
1012        let mut edits = Patch::default();
1013        self.snapshot.undo_map.insert(undo);
1014
1015        let mut cx = undo.version.clone();
1016        for edit_id in undo.counts.keys().copied() {
1017            cx.observe(edit_id);
1018        }
1019        let cx = Some(cx);
1020
1021        let mut old_fragments = self.fragments.cursor::<(VersionedFullOffset, usize)>();
1022        let mut new_fragments = old_fragments.slice(
1023            &VersionedFullOffset::Offset(undo.ranges[0].start),
1024            Bias::Right,
1025            &cx,
1026        );
1027        let mut new_ropes =
1028            RopeBuilder::new(self.visible_text.cursor(0), self.deleted_text.cursor(0));
1029        new_ropes.push_tree(new_fragments.summary().text);
1030
1031        for range in &undo.ranges {
1032            let mut end_offset = old_fragments.end(&cx).0.full_offset();
1033
1034            if end_offset < range.start {
1035                let preceding_fragments = old_fragments.slice(
1036                    &VersionedFullOffset::Offset(range.start),
1037                    Bias::Right,
1038                    &cx,
1039                );
1040                new_ropes.push_tree(preceding_fragments.summary().text);
1041                new_fragments.push_tree(preceding_fragments, &None);
1042            }
1043
1044            while end_offset <= range.end {
1045                if let Some(fragment) = old_fragments.item() {
1046                    let mut fragment = fragment.clone();
1047                    let fragment_was_visible = fragment.visible;
1048
1049                    if fragment.was_visible(&undo.version, &self.undo_map)
1050                        || undo
1051                            .counts
1052                            .contains_key(&fragment.insertion_timestamp.local())
1053                    {
1054                        fragment.visible = fragment.is_visible(&self.undo_map);
1055                        fragment.max_undos.observe(undo.id);
1056                    }
1057
1058                    let old_start = old_fragments.start().1;
1059                    let new_start = new_fragments.summary().text.visible;
1060                    if fragment_was_visible && !fragment.visible {
1061                        edits.push(Edit {
1062                            old: old_start..old_start + fragment.len,
1063                            new: new_start..new_start,
1064                        });
1065                    } else if !fragment_was_visible && fragment.visible {
1066                        edits.push(Edit {
1067                            old: old_start..old_start,
1068                            new: new_start..new_start + fragment.len,
1069                        });
1070                    }
1071                    new_ropes.push_fragment(&fragment, fragment_was_visible);
1072                    new_fragments.push(fragment, &None);
1073
1074                    old_fragments.next(&cx);
1075                    if end_offset == old_fragments.end(&cx).0.full_offset() {
1076                        let unseen_fragments = old_fragments.slice(
1077                            &VersionedFullOffset::Offset(end_offset),
1078                            Bias::Right,
1079                            &cx,
1080                        );
1081                        new_ropes.push_tree(unseen_fragments.summary().text);
1082                        new_fragments.push_tree(unseen_fragments, &None);
1083                    }
1084                    end_offset = old_fragments.end(&cx).0.full_offset();
1085                } else {
1086                    break;
1087                }
1088            }
1089        }
1090
1091        let suffix = old_fragments.suffix(&cx);
1092        new_ropes.push_tree(suffix.summary().text);
1093        new_fragments.push_tree(suffix, &None);
1094
1095        drop(old_fragments);
1096        let (visible_text, deleted_text) = new_ropes.finish();
1097        self.snapshot.fragments = new_fragments;
1098        self.snapshot.visible_text = visible_text;
1099        self.snapshot.deleted_text = deleted_text;
1100        self.subscriptions.publish_mut(&edits);
1101        Ok(())
1102    }
1103
1104    pub fn deferred_ops(&self) -> impl Iterator<Item = &Operation> {
1105        self.deferred_ops.iter()
1106    }
1107
1108    fn flush_deferred_ops(&mut self) -> Result<()> {
1109        self.deferred_replicas.clear();
1110        let mut deferred_ops = Vec::new();
1111        for op in self.deferred_ops.drain().iter().cloned() {
1112            if self.can_apply_op(&op) {
1113                self.apply_op(op)?;
1114            } else {
1115                self.deferred_replicas.insert(op.replica_id());
1116                deferred_ops.push(op);
1117            }
1118        }
1119        self.deferred_ops.insert(deferred_ops);
1120        Ok(())
1121    }
1122
1123    fn can_apply_op(&self, op: &Operation) -> bool {
1124        if self.deferred_replicas.contains(&op.replica_id()) {
1125            false
1126        } else {
1127            match op {
1128                Operation::Edit(edit) => self.version.observed_all(&edit.version),
1129                Operation::Undo { undo, .. } => self.version.observed_all(&undo.version),
1130            }
1131        }
1132    }
1133
1134    pub fn can_resolve(&self, anchor: &Anchor) -> bool {
1135        *anchor == Anchor::min()
1136            || *anchor == Anchor::max()
1137            || self.version.observed(anchor.timestamp)
1138    }
1139
1140    pub fn peek_undo_stack(&self) -> Option<&Transaction> {
1141        self.history.undo_stack.last()
1142    }
1143
1144    pub fn start_transaction(&mut self) -> Option<TransactionId> {
1145        self.start_transaction_at(Instant::now())
1146    }
1147
1148    pub fn start_transaction_at(&mut self, now: Instant) -> Option<TransactionId> {
1149        self.history.start_transaction(self.version.clone(), now)
1150    }
1151
1152    pub fn end_transaction(&mut self) -> Option<(TransactionId, clock::Global)> {
1153        self.end_transaction_at(Instant::now())
1154    }
1155
1156    pub fn end_transaction_at(&mut self, now: Instant) -> Option<(TransactionId, clock::Global)> {
1157        if let Some(transaction) = self.history.end_transaction(now) {
1158            let since = transaction.start.clone();
1159            let id = self.history.group().unwrap();
1160            Some((id, since))
1161        } else {
1162            None
1163        }
1164    }
1165
1166    pub fn base_text(&self) -> &Arc<str> {
1167        &self.history.base_text
1168    }
1169
1170    pub fn history(&self) -> impl Iterator<Item = &EditOperation> {
1171        self.history.ops.values()
1172    }
1173
1174    pub fn undo_history(&self) -> impl Iterator<Item = (&clock::Local, &[(clock::Local, u32)])> {
1175        self.undo_map
1176            .0
1177            .iter()
1178            .map(|(edit_id, undo_counts)| (edit_id, undo_counts.as_slice()))
1179    }
1180
1181    pub fn undo(&mut self) -> Option<(TransactionId, Operation)> {
1182        if let Some(transaction) = self.history.pop_undo().cloned() {
1183            let transaction_id = transaction.id;
1184            let op = self.undo_or_redo(transaction).unwrap();
1185            Some((transaction_id, op))
1186        } else {
1187            None
1188        }
1189    }
1190
1191    pub fn undo_transaction(&mut self, transaction_id: TransactionId) -> Option<Operation> {
1192        if let Some(transaction) = self.history.remove_from_undo(transaction_id).cloned() {
1193            let op = self.undo_or_redo(transaction).unwrap();
1194            Some(op)
1195        } else {
1196            None
1197        }
1198    }
1199
1200    pub fn redo(&mut self) -> Option<(TransactionId, Operation)> {
1201        if let Some(transaction) = self.history.pop_redo().cloned() {
1202            let transaction_id = transaction.id;
1203            let op = self.undo_or_redo(transaction).unwrap();
1204            Some((transaction_id, op))
1205        } else {
1206            None
1207        }
1208    }
1209
1210    pub fn redo_transaction(&mut self, transaction_id: TransactionId) -> Option<Operation> {
1211        if let Some(transaction) = self.history.remove_from_redo(transaction_id).cloned() {
1212            let op = self.undo_or_redo(transaction).unwrap();
1213            Some(op)
1214        } else {
1215            None
1216        }
1217    }
1218
1219    fn undo_or_redo(&mut self, transaction: Transaction) -> Result<Operation> {
1220        let mut counts = HashMap::default();
1221        for edit_id in transaction.edits {
1222            counts.insert(edit_id, self.undo_map.undo_count(edit_id) + 1);
1223        }
1224
1225        let undo = UndoOperation {
1226            id: self.local_clock.tick(),
1227            counts,
1228            ranges: transaction.ranges,
1229            version: transaction.start.clone(),
1230        };
1231        self.apply_undo(&undo)?;
1232        self.snapshot.version.observe(undo.id);
1233
1234        Ok(Operation::Undo {
1235            undo,
1236            lamport_timestamp: self.lamport_clock.tick(),
1237        })
1238    }
1239
1240    pub fn subscribe(&mut self) -> Subscription {
1241        self.subscriptions.subscribe()
1242    }
1243}
1244
1245#[cfg(any(test, feature = "test-support"))]
1246impl Buffer {
1247    pub fn check_invariants(&self) {
1248        // Ensure every fragment is ordered by locator in the fragment tree and corresponds
1249        // to an insertion fragment in the insertions tree.
1250        let mut prev_fragment_id = Locator::min();
1251        for fragment in self.snapshot.fragments.items(&None) {
1252            assert!(fragment.id > prev_fragment_id);
1253            prev_fragment_id = fragment.id.clone();
1254
1255            let insertion_fragment = self
1256                .snapshot
1257                .insertions
1258                .get(
1259                    &InsertionFragmentKey {
1260                        timestamp: fragment.insertion_timestamp.local(),
1261                        split_offset: fragment.insertion_offset,
1262                    },
1263                    &(),
1264                )
1265                .unwrap();
1266            assert_eq!(insertion_fragment.fragment_id, fragment.id);
1267        }
1268
1269        let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>();
1270        for insertion_fragment in self.snapshot.insertions.cursor::<()>() {
1271            cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left, &None);
1272            let fragment = cursor.item().unwrap();
1273            assert_eq!(insertion_fragment.fragment_id, fragment.id);
1274            assert_eq!(insertion_fragment.split_offset, fragment.insertion_offset);
1275        }
1276
1277        let fragment_summary = self.snapshot.fragments.summary();
1278        assert_eq!(
1279            fragment_summary.text.visible,
1280            self.snapshot.visible_text.len()
1281        );
1282        assert_eq!(
1283            fragment_summary.text.deleted,
1284            self.snapshot.deleted_text.len()
1285        );
1286    }
1287
1288    pub fn set_group_interval(&mut self, group_interval: Duration) {
1289        self.history.group_interval = group_interval;
1290    }
1291
1292    pub fn random_byte_range(&self, start_offset: usize, rng: &mut impl rand::Rng) -> Range<usize> {
1293        let end = self.clip_offset(rng.gen_range(start_offset..=self.len()), Bias::Right);
1294        let start = self.clip_offset(rng.gen_range(start_offset..=end), Bias::Right);
1295        start..end
1296    }
1297
1298    pub fn randomly_edit<T>(
1299        &mut self,
1300        rng: &mut T,
1301        old_range_count: usize,
1302    ) -> (Vec<Range<usize>>, String, Operation)
1303    where
1304        T: rand::Rng,
1305    {
1306        let mut old_ranges: Vec<Range<usize>> = Vec::new();
1307        for _ in 0..old_range_count {
1308            let last_end = old_ranges.last().map_or(0, |last_range| last_range.end + 1);
1309            if last_end > self.len() {
1310                break;
1311            }
1312            old_ranges.push(self.random_byte_range(last_end, rng));
1313        }
1314        let new_text_len = rng.gen_range(0..10);
1315        let new_text: String = crate::random_char_iter::RandomCharIter::new(&mut *rng)
1316            .take(new_text_len)
1317            .collect();
1318        log::info!(
1319            "mutating buffer {} at {:?}: {:?}",
1320            self.replica_id,
1321            old_ranges,
1322            new_text
1323        );
1324        let op = self.edit(old_ranges.iter().cloned(), new_text.as_str());
1325        (old_ranges, new_text, Operation::Edit(op))
1326    }
1327
1328    pub fn randomly_undo_redo(&mut self, rng: &mut impl rand::Rng) -> Vec<Operation> {
1329        use rand::prelude::*;
1330
1331        let mut ops = Vec::new();
1332        for _ in 0..rng.gen_range(1..=5) {
1333            if let Some(transaction) = self.history.undo_stack.choose(rng).cloned() {
1334                log::info!(
1335                    "undoing buffer {} transaction {:?}",
1336                    self.replica_id,
1337                    transaction
1338                );
1339                ops.push(self.undo_or_redo(transaction).unwrap());
1340            }
1341        }
1342        ops
1343    }
1344}
1345
1346impl Deref for Buffer {
1347    type Target = BufferSnapshot;
1348
1349    fn deref(&self) -> &Self::Target {
1350        &self.snapshot
1351    }
1352}
1353
1354impl BufferSnapshot {
1355    pub fn as_rope(&self) -> &Rope {
1356        &self.visible_text
1357    }
1358
1359    pub fn replica_id(&self) -> ReplicaId {
1360        self.replica_id
1361    }
1362
1363    pub fn row_count(&self) -> u32 {
1364        self.max_point().row + 1
1365    }
1366
1367    pub fn len(&self) -> usize {
1368        self.visible_text.len()
1369    }
1370
1371    pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
1372        self.chars_at(0)
1373    }
1374
1375    pub fn chars_for_range<T: ToOffset>(&self, range: Range<T>) -> impl Iterator<Item = char> + '_ {
1376        self.text_for_range(range).flat_map(str::chars)
1377    }
1378
1379    pub fn contains_str_at<T>(&self, position: T, needle: &str) -> bool
1380    where
1381        T: ToOffset,
1382    {
1383        let position = position.to_offset(self);
1384        position == self.clip_offset(position, Bias::Left)
1385            && self
1386                .bytes_in_range(position..self.len())
1387                .flatten()
1388                .copied()
1389                .take(needle.len())
1390                .eq(needle.bytes())
1391    }
1392
1393    pub fn text(&self) -> String {
1394        self.visible_text.to_string()
1395    }
1396
1397    pub fn deleted_text(&self) -> String {
1398        self.deleted_text.to_string()
1399    }
1400
1401    pub fn fragments(&self) -> impl Iterator<Item = &Fragment> {
1402        self.fragments.iter()
1403    }
1404
1405    pub fn text_summary(&self) -> TextSummary {
1406        self.visible_text.summary()
1407    }
1408
1409    pub fn max_point(&self) -> Point {
1410        self.visible_text.max_point()
1411    }
1412
1413    pub fn point_to_offset(&self, point: Point) -> usize {
1414        self.visible_text.point_to_offset(point)
1415    }
1416
1417    pub fn point_utf16_to_offset(&self, point: PointUtf16) -> usize {
1418        self.visible_text.point_utf16_to_offset(point)
1419    }
1420
1421    pub fn point_utf16_to_point(&self, point: PointUtf16) -> Point {
1422        self.visible_text.point_utf16_to_point(point)
1423    }
1424
1425    pub fn offset_to_point(&self, offset: usize) -> Point {
1426        self.visible_text.offset_to_point(offset)
1427    }
1428
1429    pub fn offset_to_point_utf16(&self, offset: usize) -> PointUtf16 {
1430        self.visible_text.offset_to_point_utf16(offset)
1431    }
1432
1433    pub fn version(&self) -> &clock::Global {
1434        &self.version
1435    }
1436
1437    pub fn chars_at<'a, T: ToOffset>(&'a self, position: T) -> impl Iterator<Item = char> + 'a {
1438        let offset = position.to_offset(self);
1439        self.visible_text.chars_at(offset)
1440    }
1441
1442    pub fn reversed_chars_at<'a, T: ToOffset>(
1443        &'a self,
1444        position: T,
1445    ) -> impl Iterator<Item = char> + 'a {
1446        let offset = position.to_offset(self);
1447        self.visible_text.reversed_chars_at(offset)
1448    }
1449
1450    pub fn reversed_chunks_in_range<T: ToOffset>(&self, range: Range<T>) -> rope::Chunks {
1451        let range = range.start.to_offset(self)..range.end.to_offset(self);
1452        self.visible_text.reversed_chunks_in_range(range)
1453    }
1454
1455    pub fn bytes_in_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> rope::Bytes<'a> {
1456        let start = range.start.to_offset(self);
1457        let end = range.end.to_offset(self);
1458        self.visible_text.bytes_in_range(start..end)
1459    }
1460
1461    pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> Chunks<'a> {
1462        let start = range.start.to_offset(self);
1463        let end = range.end.to_offset(self);
1464        self.visible_text.chunks_in_range(start..end)
1465    }
1466
1467    pub fn line_len(&self, row: u32) -> u32 {
1468        let row_start_offset = Point::new(row, 0).to_offset(self);
1469        let row_end_offset = if row >= self.max_point().row {
1470            self.len()
1471        } else {
1472            Point::new(row + 1, 0).to_offset(self) - 1
1473        };
1474        (row_end_offset - row_start_offset) as u32
1475    }
1476
1477    pub fn is_line_blank(&self, row: u32) -> bool {
1478        self.text_for_range(Point::new(row, 0)..Point::new(row, self.line_len(row)))
1479            .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none())
1480    }
1481
1482    pub fn indent_column_for_line(&self, row: u32) -> u32 {
1483        let mut result = 0;
1484        for c in self.chars_at(Point::new(row, 0)) {
1485            if c == ' ' {
1486                result += 1;
1487            } else {
1488                break;
1489            }
1490        }
1491        result
1492    }
1493
1494    pub fn text_summary_for_range<'a, D, O: ToOffset>(&'a self, range: Range<O>) -> D
1495    where
1496        D: TextDimension,
1497    {
1498        self.visible_text
1499            .cursor(range.start.to_offset(self))
1500            .summary(range.end.to_offset(self))
1501    }
1502
1503    pub fn summaries_for_anchors<'a, D, A>(&'a self, anchors: A) -> impl 'a + Iterator<Item = D>
1504    where
1505        D: 'a + TextDimension,
1506        A: 'a + IntoIterator<Item = &'a Anchor>,
1507    {
1508        let anchors = anchors.into_iter();
1509        let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
1510        let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>();
1511        let mut text_cursor = self.visible_text.cursor(0);
1512        let mut position = D::default();
1513
1514        anchors.map(move |anchor| {
1515            if *anchor == Anchor::min() {
1516                return D::default();
1517            } else if *anchor == Anchor::max() {
1518                return D::from_text_summary(&self.visible_text.summary());
1519            }
1520
1521            let anchor_key = InsertionFragmentKey {
1522                timestamp: anchor.timestamp,
1523                split_offset: anchor.offset,
1524            };
1525            insertion_cursor.seek(&anchor_key, anchor.bias, &());
1526            if let Some(insertion) = insertion_cursor.item() {
1527                let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
1528                if comparison == Ordering::Greater
1529                    || (anchor.bias == Bias::Left
1530                        && comparison == Ordering::Equal
1531                        && anchor.offset > 0)
1532                {
1533                    insertion_cursor.prev(&());
1534                }
1535            } else {
1536                insertion_cursor.prev(&());
1537            }
1538            let insertion = insertion_cursor.item().expect("invalid insertion");
1539            assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion");
1540
1541            fragment_cursor.seek_forward(&Some(&insertion.fragment_id), Bias::Left, &None);
1542            let fragment = fragment_cursor.item().unwrap();
1543            let mut fragment_offset = fragment_cursor.start().1;
1544            if fragment.visible {
1545                fragment_offset += anchor.offset - insertion.split_offset;
1546            }
1547
1548            position.add_assign(&text_cursor.summary(fragment_offset));
1549            position.clone()
1550        })
1551    }
1552
1553    fn summary_for_anchor<'a, D>(&'a self, anchor: &Anchor) -> D
1554    where
1555        D: TextDimension,
1556    {
1557        if *anchor == Anchor::min() {
1558            D::default()
1559        } else if *anchor == Anchor::max() {
1560            D::from_text_summary(&self.visible_text.summary())
1561        } else {
1562            let anchor_key = InsertionFragmentKey {
1563                timestamp: anchor.timestamp,
1564                split_offset: anchor.offset,
1565            };
1566            let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
1567            insertion_cursor.seek(&anchor_key, anchor.bias, &());
1568            if let Some(insertion) = insertion_cursor.item() {
1569                let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
1570                if comparison == Ordering::Greater
1571                    || (anchor.bias == Bias::Left
1572                        && comparison == Ordering::Equal
1573                        && anchor.offset > 0)
1574                {
1575                    insertion_cursor.prev(&());
1576                }
1577            } else {
1578                insertion_cursor.prev(&());
1579            }
1580            let insertion = insertion_cursor.item().expect("invalid insertion");
1581            assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion");
1582
1583            let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, usize)>();
1584            fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None);
1585            let fragment = fragment_cursor.item().unwrap();
1586            let mut fragment_offset = fragment_cursor.start().1;
1587            if fragment.visible {
1588                fragment_offset += anchor.offset - insertion.split_offset;
1589            }
1590            self.text_summary_for_range(0..fragment_offset)
1591        }
1592    }
1593
1594    fn fragment_id_for_anchor(&self, anchor: &Anchor) -> &Locator {
1595        if *anchor == Anchor::min() {
1596            &locator::MIN
1597        } else if *anchor == Anchor::max() {
1598            &locator::MAX
1599        } else {
1600            let anchor_key = InsertionFragmentKey {
1601                timestamp: anchor.timestamp,
1602                split_offset: anchor.offset,
1603            };
1604            let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>();
1605            insertion_cursor.seek(&anchor_key, anchor.bias, &());
1606            if let Some(insertion) = insertion_cursor.item() {
1607                let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
1608                if comparison == Ordering::Greater
1609                    || (anchor.bias == Bias::Left
1610                        && comparison == Ordering::Equal
1611                        && anchor.offset > 0)
1612                {
1613                    insertion_cursor.prev(&());
1614                }
1615            } else {
1616                insertion_cursor.prev(&());
1617            }
1618            let insertion = insertion_cursor.item().expect("invalid insertion");
1619            debug_assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion");
1620            &insertion.fragment_id
1621        }
1622    }
1623
1624    pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
1625        self.anchor_at(position, Bias::Left)
1626    }
1627
1628    pub fn anchor_after<T: ToOffset>(&self, position: T) -> Anchor {
1629        self.anchor_at(position, Bias::Right)
1630    }
1631
1632    pub fn anchor_at<T: ToOffset>(&self, position: T, bias: Bias) -> Anchor {
1633        let offset = position.to_offset(self);
1634        if bias == Bias::Left && offset == 0 {
1635            Anchor::min()
1636        } else if bias == Bias::Right && offset == self.len() {
1637            Anchor::max()
1638        } else {
1639            let mut fragment_cursor = self.fragments.cursor::<usize>();
1640            fragment_cursor.seek(&offset, bias, &None);
1641            let fragment = fragment_cursor.item().unwrap();
1642            let overshoot = offset - *fragment_cursor.start();
1643            Anchor {
1644                timestamp: fragment.insertion_timestamp.local(),
1645                offset: fragment.insertion_offset + overshoot,
1646                bias,
1647            }
1648        }
1649    }
1650
1651    pub fn clip_offset(&self, offset: usize, bias: Bias) -> usize {
1652        self.visible_text.clip_offset(offset, bias)
1653    }
1654
1655    pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
1656        self.visible_text.clip_point(point, bias)
1657    }
1658
1659    pub fn clip_point_utf16(&self, point: PointUtf16, bias: Bias) -> PointUtf16 {
1660        self.visible_text.clip_point_utf16(point, bias)
1661    }
1662
1663    // pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
1664    //     if offset <= self.len() {
1665    //         Ok(self.text_summary_for_range(0..offset))
1666    //     } else {
1667    //         Err(anyhow!("offset out of bounds"))
1668    //     }
1669    // }
1670
1671    pub fn edits_since<'a, D>(
1672        &'a self,
1673        since: &'a clock::Global,
1674    ) -> impl 'a + Iterator<Item = Edit<D>>
1675    where
1676        D: TextDimension + Ord,
1677    {
1678        self.edits_since_in_range(since, Anchor::min()..Anchor::max())
1679    }
1680
1681    pub fn edits_since_in_range<'a, D>(
1682        &'a self,
1683        since: &'a clock::Global,
1684        range: Range<Anchor>,
1685    ) -> impl 'a + Iterator<Item = Edit<D>>
1686    where
1687        D: TextDimension + Ord,
1688    {
1689        let fragments_cursor = if *since == self.version {
1690            None
1691        } else {
1692            Some(self.fragments.filter(
1693                move |summary| !since.observed_all(&summary.max_version),
1694                &None,
1695            ))
1696        };
1697        let mut cursor = self
1698            .fragments
1699            .cursor::<(Option<&Locator>, FragmentTextSummary)>();
1700
1701        let start_fragment_id = self.fragment_id_for_anchor(&range.start);
1702        cursor.seek(&Some(start_fragment_id), Bias::Left, &None);
1703        let mut visible_start = cursor.start().1.visible;
1704        let mut deleted_start = cursor.start().1.deleted;
1705        if let Some(fragment) = cursor.item() {
1706            let overshoot = range.start.offset - fragment.insertion_offset;
1707            if fragment.visible {
1708                visible_start += overshoot;
1709            } else {
1710                deleted_start += overshoot;
1711            }
1712        }
1713        let end_fragment_id = self.fragment_id_for_anchor(&range.end);
1714
1715        Edits {
1716            visible_cursor: self.visible_text.cursor(visible_start),
1717            deleted_cursor: self.deleted_text.cursor(deleted_start),
1718            fragments_cursor,
1719            undos: &self.undo_map,
1720            since,
1721            old_end: Default::default(),
1722            new_end: Default::default(),
1723            range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
1724        }
1725    }
1726}
1727
1728struct RopeBuilder<'a> {
1729    old_visible_cursor: rope::Cursor<'a>,
1730    old_deleted_cursor: rope::Cursor<'a>,
1731    new_visible: Rope,
1732    new_deleted: Rope,
1733}
1734
1735impl<'a> RopeBuilder<'a> {
1736    fn new(old_visible_cursor: rope::Cursor<'a>, old_deleted_cursor: rope::Cursor<'a>) -> Self {
1737        Self {
1738            old_visible_cursor,
1739            old_deleted_cursor,
1740            new_visible: Rope::new(),
1741            new_deleted: Rope::new(),
1742        }
1743    }
1744
1745    fn push_tree(&mut self, len: FragmentTextSummary) {
1746        self.push(len.visible, true, true);
1747        self.push(len.deleted, false, false);
1748    }
1749
1750    fn push_fragment(&mut self, fragment: &Fragment, was_visible: bool) {
1751        debug_assert!(fragment.len > 0);
1752        self.push(fragment.len, was_visible, fragment.visible)
1753    }
1754
1755    fn push(&mut self, len: usize, was_visible: bool, is_visible: bool) {
1756        let text = if was_visible {
1757            self.old_visible_cursor
1758                .slice(self.old_visible_cursor.offset() + len)
1759        } else {
1760            self.old_deleted_cursor
1761                .slice(self.old_deleted_cursor.offset() + len)
1762        };
1763        if is_visible {
1764            self.new_visible.append(text);
1765        } else {
1766            self.new_deleted.append(text);
1767        }
1768    }
1769
1770    fn push_str(&mut self, text: &str) {
1771        self.new_visible.push(text);
1772    }
1773
1774    fn finish(mut self) -> (Rope, Rope) {
1775        self.new_visible.append(self.old_visible_cursor.suffix());
1776        self.new_deleted.append(self.old_deleted_cursor.suffix());
1777        (self.new_visible, self.new_deleted)
1778    }
1779}
1780
1781impl<'a, D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator for Edits<'a, D, F> {
1782    type Item = Edit<D>;
1783
1784    fn next(&mut self) -> Option<Self::Item> {
1785        let mut pending_edit: Option<Edit<D>> = None;
1786        let cursor = self.fragments_cursor.as_mut()?;
1787
1788        while let Some(fragment) = cursor.item() {
1789            if fragment.id < *self.range.start.0 {
1790                cursor.next(&None);
1791                continue;
1792            } else if fragment.id > *self.range.end.0 {
1793                break;
1794            }
1795
1796            if cursor.start().visible > self.visible_cursor.offset() {
1797                let summary = self.visible_cursor.summary(cursor.start().visible);
1798                self.old_end.add_assign(&summary);
1799                self.new_end.add_assign(&summary);
1800            }
1801
1802            if pending_edit
1803                .as_ref()
1804                .map_or(false, |change| change.new.end < self.new_end)
1805            {
1806                break;
1807            }
1808
1809            if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
1810                let mut visible_end = cursor.end(&None).visible;
1811                if fragment.id == *self.range.end.0 {
1812                    visible_end = cmp::min(
1813                        visible_end,
1814                        cursor.start().visible + (self.range.end.1 - fragment.insertion_offset),
1815                    );
1816                }
1817
1818                let fragment_summary = self.visible_cursor.summary(visible_end);
1819                let mut new_end = self.new_end.clone();
1820                new_end.add_assign(&fragment_summary);
1821                if let Some(pending_edit) = pending_edit.as_mut() {
1822                    pending_edit.new.end = new_end.clone();
1823                } else {
1824                    pending_edit = Some(Edit {
1825                        old: self.old_end.clone()..self.old_end.clone(),
1826                        new: self.new_end.clone()..new_end.clone(),
1827                    });
1828                }
1829
1830                self.new_end = new_end;
1831            } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
1832                let mut deleted_end = cursor.end(&None).deleted;
1833                if fragment.id == *self.range.end.0 {
1834                    deleted_end = cmp::min(
1835                        deleted_end,
1836                        cursor.start().deleted + (self.range.end.1 - fragment.insertion_offset),
1837                    );
1838                }
1839
1840                if cursor.start().deleted > self.deleted_cursor.offset() {
1841                    self.deleted_cursor.seek_forward(cursor.start().deleted);
1842                }
1843                let fragment_summary = self.deleted_cursor.summary(deleted_end);
1844                let mut old_end = self.old_end.clone();
1845                old_end.add_assign(&fragment_summary);
1846                if let Some(pending_edit) = pending_edit.as_mut() {
1847                    pending_edit.old.end = old_end.clone();
1848                } else {
1849                    pending_edit = Some(Edit {
1850                        old: self.old_end.clone()..old_end.clone(),
1851                        new: self.new_end.clone()..self.new_end.clone(),
1852                    });
1853                }
1854
1855                self.old_end = old_end;
1856            }
1857
1858            cursor.next(&None);
1859        }
1860
1861        pending_edit
1862    }
1863}
1864
1865impl Fragment {
1866    fn is_visible(&self, undos: &UndoMap) -> bool {
1867        !undos.is_undone(self.insertion_timestamp.local())
1868            && self.deletions.iter().all(|d| undos.is_undone(*d))
1869    }
1870
1871    fn was_visible(&self, version: &clock::Global, undos: &UndoMap) -> bool {
1872        (version.observed(self.insertion_timestamp.local())
1873            && !undos.was_undone(self.insertion_timestamp.local(), version))
1874            && self
1875                .deletions
1876                .iter()
1877                .all(|d| !version.observed(*d) || undos.was_undone(*d, version))
1878    }
1879}
1880
1881impl sum_tree::Item for Fragment {
1882    type Summary = FragmentSummary;
1883
1884    fn summary(&self) -> Self::Summary {
1885        let mut max_version = clock::Global::new();
1886        max_version.observe(self.insertion_timestamp.local());
1887        for deletion in &self.deletions {
1888            max_version.observe(*deletion);
1889        }
1890        max_version.join(&self.max_undos);
1891
1892        let mut min_insertion_version = clock::Global::new();
1893        min_insertion_version.observe(self.insertion_timestamp.local());
1894        let max_insertion_version = min_insertion_version.clone();
1895        if self.visible {
1896            FragmentSummary {
1897                max_id: self.id.clone(),
1898                text: FragmentTextSummary {
1899                    visible: self.len,
1900                    deleted: 0,
1901                },
1902                max_version,
1903                min_insertion_version,
1904                max_insertion_version,
1905            }
1906        } else {
1907            FragmentSummary {
1908                max_id: self.id.clone(),
1909                text: FragmentTextSummary {
1910                    visible: 0,
1911                    deleted: self.len,
1912                },
1913                max_version,
1914                min_insertion_version,
1915                max_insertion_version,
1916            }
1917        }
1918    }
1919}
1920
1921impl sum_tree::Summary for FragmentSummary {
1922    type Context = Option<clock::Global>;
1923
1924    fn add_summary(&mut self, other: &Self, _: &Self::Context) {
1925        self.max_id.assign(&other.max_id);
1926        self.text.visible += &other.text.visible;
1927        self.text.deleted += &other.text.deleted;
1928        self.max_version.join(&other.max_version);
1929        self.min_insertion_version
1930            .meet(&other.min_insertion_version);
1931        self.max_insertion_version
1932            .join(&other.max_insertion_version);
1933    }
1934}
1935
1936impl Default for FragmentSummary {
1937    fn default() -> Self {
1938        FragmentSummary {
1939            max_id: Locator::min(),
1940            text: FragmentTextSummary::default(),
1941            max_version: clock::Global::new(),
1942            min_insertion_version: clock::Global::new(),
1943            max_insertion_version: clock::Global::new(),
1944        }
1945    }
1946}
1947
1948impl sum_tree::Item for InsertionFragment {
1949    type Summary = InsertionFragmentKey;
1950
1951    fn summary(&self) -> Self::Summary {
1952        InsertionFragmentKey {
1953            timestamp: self.timestamp,
1954            split_offset: self.split_offset,
1955        }
1956    }
1957}
1958
1959impl sum_tree::KeyedItem for InsertionFragment {
1960    type Key = InsertionFragmentKey;
1961
1962    fn key(&self) -> Self::Key {
1963        sum_tree::Item::summary(self)
1964    }
1965}
1966
1967impl InsertionFragment {
1968    fn new(fragment: &Fragment) -> Self {
1969        Self {
1970            timestamp: fragment.insertion_timestamp.local(),
1971            split_offset: fragment.insertion_offset,
1972            fragment_id: fragment.id.clone(),
1973        }
1974    }
1975
1976    fn insert_new(fragment: &Fragment) -> sum_tree::Edit<Self> {
1977        sum_tree::Edit::Insert(Self::new(fragment))
1978    }
1979}
1980
1981impl sum_tree::Summary for InsertionFragmentKey {
1982    type Context = ();
1983
1984    fn add_summary(&mut self, summary: &Self, _: &()) {
1985        *self = *summary;
1986    }
1987}
1988
1989#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1990pub struct FullOffset(pub usize);
1991
1992impl ops::AddAssign<usize> for FullOffset {
1993    fn add_assign(&mut self, rhs: usize) {
1994        self.0 += rhs;
1995    }
1996}
1997
1998impl ops::Add<usize> for FullOffset {
1999    type Output = Self;
2000
2001    fn add(mut self, rhs: usize) -> Self::Output {
2002        self += rhs;
2003        self
2004    }
2005}
2006
2007impl ops::Sub for FullOffset {
2008    type Output = usize;
2009
2010    fn sub(self, rhs: Self) -> Self::Output {
2011        self.0 - rhs.0
2012    }
2013}
2014
2015impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize {
2016    fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2017        *self += summary.text.visible;
2018    }
2019}
2020
2021impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FullOffset {
2022    fn add_summary(&mut self, summary: &FragmentSummary, _: &Option<clock::Global>) {
2023        self.0 += summary.text.visible + summary.text.deleted;
2024    }
2025}
2026
2027impl<'a> sum_tree::Dimension<'a, FragmentSummary> for Option<&'a Locator> {
2028    fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option<clock::Global>) {
2029        *self = Some(&summary.max_id);
2030    }
2031}
2032
2033impl<'a> sum_tree::SeekTarget<'a, FragmentSummary, FragmentTextSummary> for usize {
2034    fn cmp(
2035        &self,
2036        cursor_location: &FragmentTextSummary,
2037        _: &Option<clock::Global>,
2038    ) -> cmp::Ordering {
2039        Ord::cmp(self, &cursor_location.visible)
2040    }
2041}
2042
2043#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2044enum VersionedFullOffset {
2045    Offset(FullOffset),
2046    Invalid,
2047}
2048
2049impl VersionedFullOffset {
2050    fn full_offset(&self) -> FullOffset {
2051        if let Self::Offset(position) = self {
2052            *position
2053        } else {
2054            panic!("invalid version")
2055        }
2056    }
2057}
2058
2059impl Default for VersionedFullOffset {
2060    fn default() -> Self {
2061        Self::Offset(Default::default())
2062    }
2063}
2064
2065impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedFullOffset {
2066    fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<clock::Global>) {
2067        if let Self::Offset(offset) = self {
2068            let version = cx.as_ref().unwrap();
2069            if version.observed_all(&summary.max_insertion_version) {
2070                *offset += summary.text.visible + summary.text.deleted;
2071            } else if version.observed_any(&summary.min_insertion_version) {
2072                *self = Self::Invalid;
2073            }
2074        }
2075    }
2076}
2077
2078impl<'a> sum_tree::SeekTarget<'a, FragmentSummary, Self> for VersionedFullOffset {
2079    fn cmp(&self, cursor_position: &Self, _: &Option<clock::Global>) -> cmp::Ordering {
2080        match (self, cursor_position) {
2081            (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b),
2082            (Self::Offset(_), Self::Invalid) => cmp::Ordering::Less,
2083            (Self::Invalid, _) => unreachable!(),
2084        }
2085    }
2086}
2087
2088impl Operation {
2089    fn replica_id(&self) -> ReplicaId {
2090        operation_queue::Operation::lamport_timestamp(self).replica_id
2091    }
2092
2093    pub fn is_edit(&self) -> bool {
2094        match self {
2095            Operation::Edit { .. } => true,
2096            _ => false,
2097        }
2098    }
2099}
2100
2101impl operation_queue::Operation for Operation {
2102    fn lamport_timestamp(&self) -> clock::Lamport {
2103        match self {
2104            Operation::Edit(edit) => edit.timestamp.lamport(),
2105            Operation::Undo {
2106                lamport_timestamp, ..
2107            } => *lamport_timestamp,
2108        }
2109    }
2110}
2111
2112pub trait ToOffset {
2113    fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize;
2114}
2115
2116impl ToOffset for Point {
2117    fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize {
2118        snapshot.point_to_offset(*self)
2119    }
2120}
2121
2122impl ToOffset for PointUtf16 {
2123    fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize {
2124        snapshot.point_utf16_to_offset(*self)
2125    }
2126}
2127
2128impl ToOffset for usize {
2129    fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize {
2130        assert!(*self <= snapshot.len(), "offset is out of range");
2131        *self
2132    }
2133}
2134
2135impl ToOffset for Anchor {
2136    fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize {
2137        snapshot.summary_for_anchor(self)
2138    }
2139}
2140
2141impl<'a, T: ToOffset> ToOffset for &'a T {
2142    fn to_offset(&self, content: &BufferSnapshot) -> usize {
2143        (*self).to_offset(content)
2144    }
2145}
2146
2147pub trait ToPoint {
2148    fn to_point<'a>(&self, snapshot: &BufferSnapshot) -> Point;
2149}
2150
2151impl ToPoint for Anchor {
2152    fn to_point<'a>(&self, snapshot: &BufferSnapshot) -> Point {
2153        snapshot.summary_for_anchor(self)
2154    }
2155}
2156
2157impl ToPoint for usize {
2158    fn to_point<'a>(&self, snapshot: &BufferSnapshot) -> Point {
2159        snapshot.offset_to_point(*self)
2160    }
2161}
2162
2163impl ToPoint for PointUtf16 {
2164    fn to_point<'a>(&self, snapshot: &BufferSnapshot) -> Point {
2165        snapshot.point_utf16_to_point(*self)
2166    }
2167}
2168
2169impl ToPoint for Point {
2170    fn to_point<'a>(&self, _: &BufferSnapshot) -> Point {
2171        *self
2172    }
2173}
2174
2175pub trait Clip {
2176    fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self;
2177}
2178
2179impl Clip for usize {
2180    fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self {
2181        snapshot.clip_offset(*self, bias)
2182    }
2183}
2184
2185impl Clip for Point {
2186    fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self {
2187        snapshot.clip_point(*self, bias)
2188    }
2189}
2190
2191impl Clip for PointUtf16 {
2192    fn clip(&self, bias: Bias, snapshot: &BufferSnapshot) -> Self {
2193        snapshot.clip_point_utf16(*self, bias)
2194    }
2195}
2196
2197pub trait FromAnchor {
2198    fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self;
2199}
2200
2201impl FromAnchor for Point {
2202    fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
2203        snapshot.summary_for_anchor(anchor)
2204    }
2205}
2206
2207impl FromAnchor for PointUtf16 {
2208    fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
2209        snapshot.summary_for_anchor(anchor)
2210    }
2211}
2212
2213impl FromAnchor for usize {
2214    fn from_anchor(anchor: &Anchor, snapshot: &BufferSnapshot) -> Self {
2215        snapshot.summary_for_anchor(anchor)
2216    }
2217}