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