1#![cfg_attr(not(feature = "write"), no_std)]
2
3#![cfg_attr(all(not(feature = "runtime-dispatch-simd"), feature = "generic-simd"), feature(portable_simd))]
4
5#![warn(clippy::all, clippy::pedantic, dead_code, clippy::cargo)]
6#![allow(
7 unused_assignments,
8 clippy::inline_always,
9 clippy::uninlined_format_args, clippy::borrow_as_ptr,
11 clippy::negative_feature_names,
12 clippy::redundant_closure_for_method_calls,
13 clippy::sliced_string_as_bytes,
14 clippy::should_implement_trait,
15 clippy::collapsible_if,
16 clippy::new_without_default,
17 clippy::comparison_chain,
18 clippy::redundant_field_names,
19 clippy::semicolon_if_nothing_returned,
20 clippy::pub_underscore_fields,
21 clippy::struct_field_names,
22 clippy::ptr_as_ptr,
23 clippy::missing_transmute_annotations,
24 clippy::multiple_crate_versions,
25 clippy::cast_precision_loss,
26 clippy::cast_possible_truncation,
27 clippy::similar_names,
28 clippy::cast_sign_loss,
29 clippy::cast_possible_wrap,
30 clippy::used_underscore_binding,
31 clippy::nonstandard_macro_braces,
32 clippy::used_underscore_items,
33 clippy::enum_glob_use,
34 clippy::cast_lossless,
35 clippy::match_same_arms,
36 clippy::too_many_lines,
37 clippy::unnested_or_patterns,
38 clippy::blocks_in_conditions,
39 clippy::missing_errors_doc,
40 clippy::missing_panics_doc,
41)]
42
43#[cfg(feature = "write")]
44extern crate std;
45
46extern crate alloc;
47
48#[allow(unused)]
49use alloc::vec;
50use alloc::vec::Vec;
51use alloc::sync::Arc;
52use alloc::string::{String, ToString};
53
54use core::str;
55use core::cmp::Ordering;
56use core::ops::{Bound, Deref, RangeBounds};
57
58#[cfg(not(feature = "dont_vendor"))]
59mod cranelift_entity_vendor;
60#[cfg(not(feature = "dont_vendor"))]
61use cranelift_entity_vendor as cranelift_entity;
62
63#[cfg(not(feature = "dont_vendor"))]
64mod smallvec_vendor;
65#[cfg(not(feature = "dont_vendor"))]
66use smallvec_vendor as smallvec;
67
68#[cfg(not(feature = "dont_vendor"))]
69mod bytecount_vendor;
70#[cfg(not(feature = "dont_vendor"))]
71use bytecount_vendor as bytecount;
72
73use smallvec::SmallVec;
74use cranelift_entity::{EntityRef, PrimaryMap};
75#[cfg(feature = "dont_vendor")]
76use cranelift_entity::entity_impl;
77
78#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
79pub struct BufferRef(pub u32);
80entity_impl!(BufferRef);
81
82#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
83pub struct NodeRef(pub u32);
84entity_impl!(NodeRef);
85
86pub const NIL: NodeRef = NodeRef(0);
87
88pub const MOD_BUFFER: BufferRef = BufferRef(u32::MAX >> 1);
89
90pub const CHECKPOINT_INTERVAL: u32 = 64;
91
92#[derive(Clone, Copy, PartialEq, Eq, Debug)]
93pub enum Color { Black = 0, Red = 1 }
94
95#[derive(Clone, Copy, Debug)]
96pub struct HistoryEntry {
97 pub root: NodeRef,
98 pub cursor_offset: u32,
99}
100
101#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
102pub struct Piece {
103 pub buffer: BufferRef,
104
105 pub byte_offset: u32,
106 pub byte_length: u32,
107
108 pub newline_count: u32,
109 pub char_count: u32,
110
111 pub buffer_start_line: u32, pub piece_start_char: u32, }
115
116#[derive(Clone, Copy, Debug)]
118pub enum Edit {
119 Insert { offset: u32, text: &'static str },
120 Remove { offset: u32, length: u32 },
121}
122
123impl Edit {
124 #[inline(always)]
125 #[must_use]
126 pub fn offset(&self) -> u32 {
127 match self {
128 Edit::Insert { offset, .. } => *offset,
129 Edit::Remove { offset, .. } => *offset,
130 }
131 }
132}
133
134#[derive(Clone, Copy, Debug)]
135#[repr(C)]
136pub struct Node {
137 pub left: NodeRef, pub right: NodeRef, pub offset: u32, pub subtree_len: u32, pub subtree_chars: u32, pub subtree_newlines: u32, pub meta: u32, pub buffer_start_line: u32, pub piece_start_char: u32, }
147
148const _: () = assert!(size_of::<Node>() == 36);
149
150impl Node {
151 #[inline(always)]
152 #[must_use]
153 pub fn color(&self) -> Color {
154 if (self.meta & 1) == 1 { Color::Red } else { Color::Black }
155 }
156
157 #[inline(always)]
158 pub fn set_color(&mut self, color: Color) {
159 self.meta = (self.meta & !1) | (color as u32);
160 }
161
162 #[inline(always)]
163 #[must_use]
164 pub fn buffer_index(&self) -> BufferRef {
165 BufferRef(self.meta >> 1)
166 }
167
168 #[inline(always)]
169 pub fn set_buffer(&mut self, buffer: BufferRef) {
170 self.meta = (buffer.as_u32() << 1) | (self.meta & 1);
171 }
172}
173
174#[derive(Debug, Clone)]
175pub struct OriginalBuffer {
176 pub text: Arc<str>,
177 pub newline_offsets: Arc<[u32]>,
178 pub char_checkpoints: Arc<[(u32, u32)]>,
179}
180
181impl Deref for OriginalBuffer {
182 type Target = str;
183
184 #[inline(always)]
185 fn deref(&self) -> &Self::Target {
186 self.text.as_ref()
187 }
188}
189
190#[derive(Debug, Clone)]
191pub struct Buffers {
192 pub original_buffers: PrimaryMap<BufferRef, OriginalBuffer>,
193
194 pub modifications_char_count: u32,
195 pub modifications_buffer: String,
196 pub modifications_newline_offsets: Vec<u32>,
197 pub modifications_char_checkpoints: Vec<(u32, u32)>,
198}
199
200impl Default for Buffers {
201 #[inline(always)]
202 fn default() -> Self {
203 Self {
204 original_buffers: PrimaryMap::new(),
205 modifications_char_count: 0,
206 modifications_newline_offsets: Vec::with_capacity(1024),
207 modifications_char_checkpoints: Vec::with_capacity(128),
208 modifications_buffer: String::with_capacity(1024 * 64),
209 }
210 }
211}
212
213#[must_use]
214#[inline(always)]
215pub fn count_chars_and_newlines(bytes: &[u8]) -> (u32, u32) {
216 let mut chars = 0u32;
217 let mut newlines = 0u32;
218
219 for &b in bytes {
220 newlines += (b == b'\n') as u32;
221 chars += ((b & 0xC0) != 0x80) as u32;
222 }
223
224 (chars, newlines)
225}
226
227#[must_use]
228#[inline(always)]
229pub fn count_chars_and_newlines_with_offsets_and_checkpoints(
230 bytes: &[u8],
231 offsets: &mut Vec<u32>,
232 checkpoints: &mut Vec<(u32, u32)>,
233) -> (u32, u32) {
234 let mut chars = 0u32;
235 let mut newlines = 0u32;
236
237 let mut next_checkpoint = CHECKPOINT_INTERVAL;
238
239 for (i, &b) in bytes.iter().enumerate() {
240 if (b as i8) >= -0x40 {
241 if chars == next_checkpoint {
242 checkpoints.push((chars, i as u32));
243 next_checkpoint += CHECKPOINT_INTERVAL;
244 }
245 chars += 1;
246 }
247
248 if b == b'\n' {
249 offsets.push(i as u32);
250 newlines += 1;
251 }
252 }
253
254 (chars, newlines)
255}
256
257impl Buffers {
258 #[inline(always)]
259 #[must_use]
260 pub fn new() -> Self { Self::default() }
261
262 #[inline(always)]
263 #[must_use]
264 pub fn get(&self, buffer: BufferRef) -> &str {
265 if buffer == MOD_BUFFER {
266 &self.modifications_buffer
267 } else {
268 &self.original_buffers[buffer]
269 }
270 }
271
272 #[inline(always)]
273 #[must_use]
274 pub fn get_slice(&self, buffer: BufferRef, offset: u32, len: u32) -> &str {
275 let buf = self.get(buffer);
276 let start = offset as usize;
277 let end = start + len as usize;
278 unsafe { str::from_utf8_unchecked(buf.as_bytes().get_unchecked(start..end)) }
279 }
280
281 #[inline]
282 #[must_use]
283 pub fn count_chars_and_newlines(&self, buffer: BufferRef, start_offset: u32, len: u32) -> (u32, u32) {
284 if len == 0 { return (0, 0) }
285
286 let end_offset = start_offset + len;
287
288 let nl_offsets = self.get_newlines(buffer);
292 let start_nl_index = nl_offsets.binary_search(&start_offset).unwrap_or_else(|x| x);
293 let end_nl_index = nl_offsets.binary_search(&end_offset).unwrap_or_else(|x| x);
294 let newlines = (end_nl_index - start_nl_index) as u32;
295
296 let checkpoints = self.get_checkpoints(buffer);
301 let buffer_text = self.get(buffer);
302
303 let chars_up_to = |target_offset: u32| -> u32 {
307 if target_offset == 0 { return 0; }
308
309 let partition_index = checkpoints.partition_point(|&(_char_cnt, byte_offset)| byte_offset <= target_offset);
313
314 let (base_chars, base_bytes) = if partition_index > 0 {
315 checkpoints[partition_index - 1]
316 } else {
317 (0, 0)
318 };
319
320 let tail_bytes = &buffer_text[base_bytes as usize .. target_offset as usize];
324 base_chars + bytecount::num_chars(tail_bytes.as_bytes()) as u32
325 };
326
327 let chars = chars_up_to(end_offset) - chars_up_to(start_offset);
328
329 (chars, newlines)
330 }
331
332 #[inline(always)]
333 #[must_use]
334 pub fn count_chars(&self, buffer: BufferRef, offset: u32, len: u32) -> u32 {
335 bytecount::num_chars(self.get_slice(buffer, offset, len).as_bytes()) as u32
336 }
337
338 #[inline(always)]
339 #[must_use]
340 pub fn count_newlines(&self, buffer: BufferRef, offset: u32, len: u32) -> u32 {
341 bytecount::count(self.get_slice(buffer, offset, len).as_bytes(), b'\n') as _
342 }
343
344 #[inline(always)]
345 fn get_newlines(&self, buffer: BufferRef) -> &[u32] {
346 if buffer == MOD_BUFFER {
347 &self.modifications_newline_offsets
348 } else {
349 &self.original_buffers[buffer].newline_offsets
350 }
351 }
352
353 #[inline(always)]
354 fn get_checkpoints(&self, buffer: BufferRef) -> &[(u32, u32)] {
355 if buffer == MOD_BUFFER {
356 &self.modifications_char_checkpoints
357 } else {
358 &self.original_buffers[buffer].char_checkpoints
359 }
360 }
361
362 #[must_use]
364 #[inline]
365 pub fn char_to_byte_absolute(&self, buffer: BufferRef, target_char: u32) -> u32 {
366 if target_char == 0 { return 0; }
367
368 let checkpoints = self.get_checkpoints(buffer);
369 let cp_index = checkpoints.partition_point(|&(c, _)| c <= target_char);
370
371 let (current_char, current_byte) = if cp_index == 0 {
372 (0, 0)
373 } else {
374 unsafe { *checkpoints.get_unchecked(cp_index - 1) }
375 };
376
377 let remainder_chars = target_char - current_char;
378 if remainder_chars == 0 { return current_byte; }
379
380 let text = self.get(buffer);
381 let slice = unsafe { text.get_unchecked(current_byte as usize..) };
382
383 let additional_bytes = slice
384 .char_indices()
385 .nth(remainder_chars as usize).map_or_else(|| slice.len() as u32, |(b, _)| b as u32); current_byte + additional_bytes
388 }
389
390 #[must_use]
392 #[inline]
393 pub fn byte_to_char_absolute(&self, buffer: BufferRef, target_byte: u32) -> u32 {
394 if target_byte == 0 { return 0; }
395
396 let checkpoints = self.get_checkpoints(buffer);
397 let cp_index = checkpoints.partition_point(|&(_, b)| b <= target_byte);
398
399 let (current_char, current_byte) = if cp_index == 0 {
400 (0, 0)
401 } else {
402 unsafe { *checkpoints.get_unchecked(cp_index - 1) }
403 };
404
405 let remainder_bytes = target_byte - current_byte;
406 if remainder_bytes == 0 { return current_char; }
407
408 let text = self.get(buffer);
409 let slice = unsafe { text.get_unchecked(current_byte as usize..target_byte as usize) };
410 let additional_chars = bytecount::num_chars(slice.as_bytes()) as u32;
411
412 current_char + additional_chars
413 }
414}
415
416#[derive(Debug, Clone)]
417pub struct Pieces {
418 pub nodes: PrimaryMap<NodeRef, Node>,
419}
420
421impl Default for Pieces {
422 #[inline(always)]
423 fn default() -> Self {
424 Self::new()
425 }
426}
427
428impl Pieces {
429 #[inline(always)]
430 #[must_use]
431 pub fn new() -> Self {
432 let mut nodes = PrimaryMap::new();
433 nodes.push(Node {
434 left: NIL, right: NIL, offset: 0,
435 subtree_len: 0, subtree_chars: 0, subtree_newlines: 0,
436 meta: 0, buffer_start_line: 0,
437 piece_start_char: 0
438 });
439 Self { nodes }
440 }
441
442 #[inline(always)]
443 #[must_use]
444 pub fn len(&self) -> usize { self.nodes.len() }
445
446 #[inline(always)]
447 #[must_use]
448 pub fn is_empty(&self) -> bool { self.nodes.is_empty() }
449
450 #[inline(always)]
451 #[must_use]
452 pub fn get(&self, index: NodeRef) -> &Node { &self.nodes[index] }
453
454 #[inline(always)]
455 #[must_use]
456 pub fn get_piece(&self, index: NodeRef) -> Piece {
457 if index == NIL { return Piece::default(); }
458
459 let node = &self.nodes[index];
460 let l = &self.nodes[node.left];
461 let r = &self.nodes[node.right];
462
463 Piece {
464 buffer: node.buffer_index(),
465 byte_offset: node.offset,
466 byte_length: node.subtree_len - l.subtree_len - r.subtree_len,
467 char_count: node.subtree_chars - l.subtree_chars - r.subtree_chars,
468 newline_count: node.subtree_newlines - l.subtree_newlines - r.subtree_newlines,
469 buffer_start_line: node.buffer_start_line,
470 piece_start_char: node.piece_start_char,
471 }
472 }
473
474 #[inline(always)]
475 pub fn alloc(&mut self, color: Color, left: NodeRef, piece: Piece, right: NodeRef) -> NodeRef {
476 let l = &self.nodes[left];
477 let r = &self.nodes[right];
478
479 let mut node = Node {
480 left, right,
481 offset: piece.byte_offset,
482 subtree_len: l.subtree_len + piece.byte_length + r.subtree_len,
483 subtree_chars: l.subtree_chars + piece.char_count + r.subtree_chars,
484 subtree_newlines: l.subtree_newlines + piece.newline_count + r.subtree_newlines,
485 buffer_start_line: piece.buffer_start_line,
486 piece_start_char: piece.piece_start_char,
487 meta: 0,
488 };
489 node.set_color(color);
490 node.set_buffer(piece.buffer);
491
492 self.nodes.push(node)
493 }
494
495 pub fn extend_piece(
498 &mut self,
499 root: NodeRef,
500 piece_start_offset: u32,
501 add_len: u32,
502 add_chars: u32,
503 add_nl: u32,
504 ) -> NodeRef {
505 if root == NIL { return NIL }
506
507 let node = self.nodes[root];
508 let mut new_node = node;
509
510 let left_len = self.nodes[node.left].subtree_len;
511 let piece_len = node.subtree_len - left_len - self.nodes[node.right].subtree_len;
512
513 if piece_start_offset < left_len {
514 new_node.left = self.extend_piece(node.left, piece_start_offset, add_len, add_chars, add_nl);
515 } else if piece_start_offset > left_len {
516 new_node.right = self.extend_piece(node.right, piece_start_offset - (left_len + piece_len), add_len, add_chars, add_nl);
517 } else {
518 }
521
522 new_node.subtree_len += add_len;
523 new_node.subtree_chars += add_chars;
524 new_node.subtree_newlines += add_nl;
525
526 self.nodes.push(new_node)
527 }
528
529 #[inline]
530 pub fn insert_node(&mut self, root: NodeRef, piece: Piece, at: u32) -> NodeRef {
531 let new_root = self.ins(root, piece, at, 0);
532 let r_node = self.nodes[new_root];
533 let p = self.get_piece(new_root);
534 self.alloc(Color::Black, r_node.left, p, r_node.right)
535 }
536
537 #[inline]
538 pub fn remove_node(&mut self, root: NodeRef, at: u32) -> NodeRef {
539 let new_root = self.rem(root, at, 0);
540 if new_root == NIL { return NIL }
541
542 let r_node = self.nodes[new_root];
543 self.alloc(Color::Black, r_node.left, self.get_piece(new_root), r_node.right)
544 }
545
546 #[inline]
547 fn rem(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
548 if root == NIL { return NIL }
549
550 let node = self.nodes[root];
551 let node_piece = self.get_piece(root);
552 let left_len = self.nodes[node.left].subtree_len;
553
554 match at.cmp(&(total + left_len)) {
555 Ordering::Less => self.remove_left(root, at, total),
556 Ordering::Equal => self.fuse(node.left, node.right),
557 Ordering::Greater => {
558 let next_total = total + left_len + node_piece.byte_length;
559 self.remove_right(root, at, next_total)
560 }
561 }
562 }
563
564 #[inline]
565 fn remove_left(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
566 let node = self.nodes[root];
567 let new_left = self.rem(node.left, at, total);
568 let new_node = self.alloc(Color::Red, new_left, self.get_piece(root), node.right);
569 if self.nodes[node.left].color() == Color::Black {
570 self.balance_left(new_node)
571 } else {
572 new_node
573 }
574 }
575
576 #[inline]
577 fn remove_right(&mut self, root: NodeRef, at: u32, total: u32) -> NodeRef {
578 let node = self.nodes[root];
579 let new_right = self.rem(node.right, at, total);
580 let new_node = self.alloc(Color::Red, node.left, self.get_piece(root), new_right);
581 if self.nodes[node.right].color() == Color::Black {
582 self.balance_right(new_node)
583 } else {
584 new_node
585 }
586 }
587
588 #[inline]
589 fn ins(&mut self, root: NodeRef, p: Piece, at: u32, total_offset: u32) -> NodeRef {
590 if root == NIL { return self.alloc(Color::Red, NIL, p, NIL); }
591
592 let node = self.nodes[root];
593 let node_piece = self.get_piece(root);
594 let left_len = self.nodes[node.left].subtree_len;
595
596 if at < total_offset + left_len + node_piece.byte_length {
597 let lft = self.ins(node.left, p, at, total_offset);
598 self.balance(node.color(), lft, node_piece, node.right)
599 } else {
600 let next_offset = total_offset + left_len + node_piece.byte_length;
601 let rgt = self.ins(node.right, p, at, next_offset);
602 self.balance(node.color(), node.left, node_piece, rgt)
603 }
604 }
605
606 #[inline]
607 fn balance(&mut self, c: Color, l_index: NodeRef, p: Piece, r_index: NodeRef) -> NodeRef {
608 let l = self.nodes[l_index];
609 let r = self.nodes[r_index];
610
611 if c == Color::Black {
612 if l.color() == Color::Red {
613 let ll = self.nodes[l.left];
614 let lr = self.nodes[l.right];
615 if ll.color() == Color::Red {
616 let new_l = self.alloc(Color::Black, ll.left, self.get_piece(l.left), ll.right);
617 let new_r = self.alloc(Color::Black, l.right, p, r_index);
618 return self.alloc(Color::Red, new_l, self.get_piece(l_index), new_r);
619 } else if lr.color() == Color::Red {
620 let new_l = self.alloc(Color::Black, l.left, self.get_piece(l_index), lr.left);
621 let new_r = self.alloc(Color::Black, lr.right, p, r_index);
622 return self.alloc(Color::Red, new_l, self.get_piece(l.right), new_r);
623 }
624 }
625
626 if r.color() == Color::Red {
627 let rl = self.nodes[r.left];
628 let rr = self.nodes[r.right];
629 if rl.color() == Color::Red {
630 let new_l = self.alloc(Color::Black, l_index, p, rl.left);
631 let new_r = self.alloc(Color::Black, rl.right, self.get_piece(r_index), r.right);
632 return self.alloc(Color::Red, new_l, self.get_piece(r.left), new_r);
633 } else if rr.color() == Color::Red {
634 let new_l = self.alloc(Color::Black, l_index, p, r.left);
635 let new_r = self.alloc(Color::Black, rr.left, self.get_piece(r.right), rr.right);
636 return self.alloc(Color::Red, new_l, self.get_piece(r_index), new_r);
637 }
638 }
639 }
640
641 self.alloc(c, l_index, p, r_index)
642 }
643
644 #[inline]
645 fn fuse(&mut self, left: NodeRef, right: NodeRef) -> NodeRef {
646 if left == NIL { return right }
650 if right == NIL { return left }
651
652 let l_node = self.nodes[left];
653 let r_node = self.nodes[right];
654
655 if l_node.color() == Color::Black && r_node.color() == Color::Red {
659 let fused = self.fuse(left, r_node.left);
660 return self.alloc(Color::Red, fused, self.get_piece(right), r_node.right);
661 }
662
663 if l_node.color() == Color::Red && r_node.color() == Color::Black {
665 let fused = self.fuse(l_node.right, right);
666 return self.alloc(Color::Red, l_node.left, self.get_piece(left), fused);
667 }
668
669 if l_node.color() == Color::Red && r_node.color() == Color::Red {
671 let fused = self.fuse(l_node.right, r_node.left);
672 let f_node = self.nodes[fused];
673 if fused != NIL && f_node.color() == Color::Red {
674 let new_l = self.alloc(Color::Red, l_node.left, self.get_piece(left), f_node.left);
675 let new_r = self.alloc(Color::Red, f_node.right, self.get_piece(right), r_node.right);
676 return self.alloc(Color::Red, new_l, self.get_piece(fused), new_r);
677 }
678 let new_r = self.alloc(Color::Red, fused, self.get_piece(right), r_node.right);
679 return self.alloc(Color::Red, l_node.left, self.get_piece(left), new_r);
680 }
681
682 let fused = self.fuse(l_node.right, r_node.left);
685 let f_node = self.nodes[fused];
686 if fused != NIL && f_node.color() == Color::Red {
687 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), f_node.left);
688 let new_r = self.alloc(Color::Black, f_node.right, self.get_piece(right), r_node.right);
689 return self.alloc(Color::Red, new_l, self.get_piece(fused), new_r);
690 }
691
692 let new_r = self.alloc(Color::Black, fused, self.get_piece(right), r_node.right);
693 let new_node = self.alloc(Color::Red, l_node.left, self.get_piece(left), new_r);
694 self.balance_left(new_node)
695 }
696
697 #[inline]
698 fn balance_left(&mut self, left: NodeRef) -> NodeRef {
699 let l_node = self.nodes[left];
700 let ll_node = self.nodes[l_node.left];
701 let lr_node = self.nodes[l_node.right];
702
703 if l_node.left != NIL && ll_node.color() == Color::Red {
707 let new_ll = self.alloc(Color::Black, ll_node.left, self.get_piece(l_node.left), ll_node.right);
708 return self.alloc(Color::Red, new_ll, self.get_piece(left), l_node.right);
709 }
710
711 if l_node.right != NIL && lr_node.color() == Color::Black {
713 let new_lr = self.alloc(Color::Red, lr_node.left, self.get_piece(l_node.right), lr_node.right);
714 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), new_lr);
715 let nl = self.nodes[new_l];
716 return self.balance(Color::Black, nl.left, self.get_piece(new_l), nl.right);
717 }
718
719 if l_node.right != NIL && lr_node.color() == Color::Red {
721 let lrl_node = self.nodes[lr_node.left];
722 if lr_node.left != NIL && lrl_node.color() == Color::Black {
723 let lrr_node = self.nodes[lr_node.right];
724 let new_lrr = self.alloc(Color::Red, lrr_node.left, self.get_piece(lr_node.right), lrr_node.right);
725 let unbal_r = self.alloc(Color::Black, lrl_node.right, self.get_piece(l_node.right), new_lrr);
726 let ur_node = self.nodes[unbal_r];
727 let new_r = self.balance(ur_node.color(), ur_node.left, self.get_piece(unbal_r), ur_node.right);
728 let new_l = self.alloc(Color::Black, l_node.left, self.get_piece(left), lrl_node.left);
729 return self.alloc(Color::Red, new_l, self.get_piece(lr_node.left), new_r);
730 }
731 }
732
733 left
734 }
735
736 #[inline]
737 fn balance_right(&mut self, right: NodeRef) -> NodeRef {
738 let r_node = self.nodes[right];
739 let rl_node = self.nodes[r_node.left];
740 let rr_node = self.nodes[r_node.right];
741
742 if r_node.right != NIL && rr_node.color() == Color::Red {
746 let new_rr = self.alloc(Color::Black, rr_node.left, self.get_piece(r_node.right), rr_node.right);
747 return self.alloc(Color::Red, r_node.left, self.get_piece(right), new_rr);
748 }
749
750 if r_node.left != NIL && rl_node.color() == Color::Black {
752 let new_rl = self.alloc(Color::Red, rl_node.left, self.get_piece(r_node.left), rl_node.right);
753 let new_r = self.alloc(Color::Black, new_rl, self.get_piece(right), r_node.right);
754 let nr = self.nodes[new_r];
755 return self.balance(Color::Black, nr.left, self.get_piece(new_r), nr.right);
756 }
757
758 if r_node.left != NIL && rl_node.color() == Color::Red {
760 let rlr_node = self.nodes[rl_node.right];
761 if rl_node.right != NIL && rlr_node.color() == Color::Black {
762 let rll_node = self.nodes[rl_node.left];
763 let new_rll = self.alloc(Color::Red, rll_node.left, self.get_piece(rl_node.left), rll_node.right);
764 let unbal_l = self.alloc(Color::Black, new_rll, self.get_piece(r_node.left), rlr_node.left);
765 let ul_node = self.nodes[unbal_l];
766 let new_l = self.balance(ul_node.color(), ul_node.left, self.get_piece(unbal_l), ul_node.right);
767 let new_r = self.alloc(Color::Black, rlr_node.right, self.get_piece(right), r_node.right);
768 return self.alloc(Color::Red, new_l, self.get_piece(rl_node.right), new_r);
769 }
770 }
771
772 right
773 }
774
775 #[inline]
776 #[must_use]
777 pub fn find_offset(
778 &self,
779 mut root: NodeRef,
780 mut target_offset: u32,
781 prefer_left: bool
782 ) -> Option<(NodeRef, u32)> {
783 while root != NIL {
784 let node = &self.nodes[root];
785 let left_len = self.nodes[node.left].subtree_len;
786 let piece_len = self.get_piece(root).byte_length;
787
788 if target_offset < left_len {
789 root = node.left;
790
791 } else if target_offset == left_len + piece_len && prefer_left {
792 return Some((root, piece_len));
794
795 } else if target_offset < left_len + piece_len {
796 return Some((root, target_offset - left_len));
797
798 } else {
799 target_offset -= left_len + piece_len;
800 root = node.right;
801 }
802 }
803
804 None
805 }
806}
807
808impl PieceTree {
809 #[inline]
811 pub fn split(&mut self, root: NodeRef, offset: u32) -> (NodeRef, NodeRef) {
812 if root == NIL {
813 return (NIL, NIL);
814 }
815
816 let node = self.pieces.nodes[root];
817 let p = self.pieces.get_piece(root);
818 let left_len = self.pieces.nodes[node.left].subtree_len;
819
820 if offset < left_len {
821 let (ll, lr) = self.split(node.left, offset);
822
823 let new_right = self.pieces.join_with_middle(lr, p, node.right);
825 (ll, new_right)
826
827 } else if offset > left_len + p.byte_length {
828 let (rl, rr) = self.split(node.right, offset - left_len - p.byte_length);
829
830 let new_left = self.pieces.join_with_middle(node.left, p, rl);
832 (new_left, rr)
833
834 } else {
835 let rel_offset = offset - left_len;
836
837 if rel_offset == 0 {
838 (node.left, self.pieces.join_with_middle(NIL, p, node.right))
839
840 } else if rel_offset == p.byte_length {
841 (self.pieces.join_with_middle(node.left, p, NIL), node.right)
842
843 } else {
844 let left_len = rel_offset;
848 let right_len = p.byte_length - rel_offset;
849
850 let (left_chars, left_nl) = if left_len <= right_len {
854 self.buffers.count_chars_and_newlines(p.buffer, p.byte_offset, left_len)
856 } else {
857 let (r_chars, r_nl) = self.buffers.count_chars_and_newlines(
859 p.buffer, p.byte_offset + left_len, right_len
860 );
861
862 (p.char_count - r_chars, p.newline_count - r_nl)
863 };
864
865 let left_stump = Piece {
866 buffer: p.buffer,
867 byte_offset: p.byte_offset,
868 byte_length: left_len,
869 newline_count: left_nl,
870 char_count: left_chars,
871 buffer_start_line: p.buffer_start_line,
872 piece_start_char: p.piece_start_char,
873 };
874
875 let right_stump = Piece {
876 buffer: p.buffer,
877 byte_offset: p.byte_offset + left_len,
878 byte_length: right_len,
879 newline_count: p.newline_count - left_nl,
880 char_count: p.char_count - left_chars,
881 buffer_start_line: p.buffer_start_line + left_nl,
882 piece_start_char: p.piece_start_char + left_chars,
883 };
884
885 let new_left = self.pieces.join_with_middle(node.left, left_stump, NIL);
886 let new_right = self.pieces.join_with_middle(NIL, right_stump, node.right);
887 (new_left, new_right)
888 }
889 }
890 }
891
892 #[inline]
894 pub fn concat(&mut self, left: NodeRef, right: NodeRef) -> NodeRef {
895 let new_root = if left == NIL {
899 right
900 } else if right == NIL {
901 left
902 } else {
903 let mut curr = left;
904 while self.pieces.nodes[curr].right != NIL {
905 curr = self.pieces.nodes[curr].right;
906 }
907 let max_piece = self.pieces.get_piece(curr);
908 let max_offset = self.pieces.nodes[left].subtree_len - max_piece.byte_length;
909
910 let left_without_max = self.pieces.remove_node(left, max_offset);
911
912 self.pieces.join_with_middle(left_without_max, max_piece, right)
913 };
914
915 if new_root != NIL && self.pieces.nodes[new_root].color() == Color::Red {
919 let p = self.pieces.get_piece(new_root);
920 let r = self.pieces.nodes[new_root];
921 return self.pieces.alloc(Color::Black, r.left, p, r.right);
922 }
923
924 new_root
925 }
926}
927
928impl Pieces {
929 #[inline(always)]
931 #[must_use]
932 pub fn black_height(&self, mut node: NodeRef) -> u32 {
933 let mut h = 0;
934 while node != NIL {
935 if self.nodes[node].color() == Color::Black {
936 h += 1;
937 }
938 node = self.nodes[node].left;
939 }
940 h
941 }
942
943 #[inline(always)]
945 pub fn join_with_middle(&mut self, left: NodeRef, piece: Piece, right: NodeRef) -> NodeRef {
946 let hl = self.black_height(left);
947 let hr = self.black_height(right);
948
949 let new_root = if hl > hr {
950 self.join_right(left, piece, right, hl, hr)
951 } else if hr > hl {
952 self.join_left(left, piece, right, hl, hr)
953 } else {
954 self.alloc(Color::Red, left, piece, right)
955 };
956
957 if new_root != NIL && self.nodes[new_root].color() == Color::Red {
959 let p = self.get_piece(new_root);
960 let r = self.nodes[new_root];
961 return self.alloc(Color::Black, r.left, p, r.right);
962 }
963
964 new_root
965 }
966
967 #[inline(always)]
968 fn join_right(&mut self, left: NodeRef, piece: Piece, right: NodeRef, hl: u32, hr: u32) -> NodeRef {
969 if hl == hr {
970 return self.alloc(Color::Red, left, piece, right);
971 }
972
973 let l_node = self.nodes[left];
974 let next_hl = if l_node.color() == Color::Black { hl - 1 } else { hl };
975
976 let new_right = self.join_right(l_node.right, piece, right, next_hl, hr);
977 let p = self.get_piece(left);
978
979 self.balance(l_node.color(), l_node.left, p, new_right)
980 }
981
982 #[inline(always)]
983 fn join_left(&mut self, left: NodeRef, piece: Piece, right: NodeRef, hl: u32, hr: u32) -> NodeRef {
984 if hl == hr {
985 return self.alloc(Color::Red, left, piece, right);
986 }
987
988 let r_node = self.nodes[right];
989 let next_hr = if r_node.color() == Color::Black { hr - 1 } else { hr };
990
991 let new_left = self.join_left(left, piece, r_node.left, hl, next_hr);
992 let p = self.get_piece(right);
993
994 self.balance(r_node.color(), new_left, p, r_node.right)
995 }
996}
997
998#[derive(Debug, Clone)]
999pub struct PieceTree {
1000 last_mod_end: u32, last_tree_end: u32, pub root: NodeRef,
1010
1011 pub transaction_depth: usize,
1013
1014 pub undo_stack: Vec<HistoryEntry>,
1015 pub redo_stack: Vec<HistoryEntry>,
1016
1017 pub pieces: Pieces,
1018 pub buffers: Buffers,
1019
1020 pub scratch_index_map: Vec<u32>,
1021}
1022
1023impl Default for PieceTree {
1024 fn default() -> Self {
1025 Self {
1026 last_mod_end: u32::MAX,
1027 last_tree_end: u32::MAX,
1028 root: NIL,
1029 transaction_depth: 0,
1030 undo_stack: Vec::new(),
1031 redo_stack: Vec::new(),
1032 pieces: Pieces::new(),
1033 buffers: Buffers::new(),
1034 scratch_index_map: Vec::new(),
1035 }
1036 }
1037}
1038
1039impl core::fmt::Display for PieceTree {
1040 #[inline(always)]
1041 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1042 for chunk in self.slice(..).chunks() {
1043 f.write_str(chunk)?;
1044 }
1045
1046 Ok(())
1047 }
1048}
1049
1050impl<T> From<T> for PieceTree where T: AsRef<str> {
1051 #[inline(always)]
1052 fn from(value: T) -> Self {
1053 Self::from_arc_str(value.as_ref())
1054 }
1055}
1056
1057impl str::FromStr for PieceTree {
1058 type Err = core::convert::Infallible;
1059
1060 #[inline(always)]
1061 fn from_str(s: &str) -> Result<Self, Self::Err> {
1062 Ok(PieceTree::from(s))
1063 }
1064}
1065
1066impl PieceTree {
1067 #[inline(always)]
1068 #[must_use]
1069 pub fn new() -> Self {
1070 Self::default()
1071 }
1072
1073 #[inline(always)]
1074 #[must_use]
1075 pub fn from_arc_str(text: impl Into<Arc<str>>) -> Self {
1076 let text = text.into();
1077
1078 let mut tree = PieceTree::new();
1079 if text.is_empty() { return tree; }
1080
1081 let bytes = text.as_bytes();
1082 let byte_length = bytes.len() as u32;
1083
1084 let mut offsets = Vec::with_capacity(bytes.len() / 40);
1085 let mut checkpoints = Vec::with_capacity(bytes.len() / 256);
1086
1087 let (char_count, newline_count) =
1088 count_chars_and_newlines_with_offsets_and_checkpoints(
1089 text.as_bytes(),
1090 &mut offsets,
1091 &mut checkpoints,
1092 );
1093
1094 let buffer = tree.buffers.original_buffers.push(OriginalBuffer {
1095 newline_offsets: offsets.into(),
1096 char_checkpoints: checkpoints.into(),
1097 text: text.into(),
1098 });
1099
1100 let piece = Piece {
1101 buffer,
1102 byte_offset: 0,
1103 byte_length,
1104 char_count,
1105 newline_count,
1106 buffer_start_line: 0,
1107 piece_start_char: 0,
1108 };
1109
1110 tree.root = tree.pieces.insert_node(NIL, piece, 0);
1111 tree
1112 }
1113
1114 pub fn split_off(&mut self, byte_offset: u32) -> Self {
1124 assert!(
1125 byte_offset <= self.len_bytes(),
1126 "split_off: byte_offset {} out of bounds (len = {})",
1127 byte_offset, self.len_bytes()
1128 );
1129
1130 if byte_offset == 0 {
1131 let mut right = Self::default();
1135 right.pieces = self.pieces.clone();
1136 right.buffers = self.buffers.clone();
1137 right.root = self.root;
1138 self.root = NIL;
1139 self.last_mod_end = u32::MAX;
1140 self.last_tree_end = u32::MAX;
1141
1142 return right;
1143 }
1144
1145 if byte_offset == self.len_bytes() {
1146 let mut right = Self::default();
1151 right.pieces = self.pieces.clone();
1152 right.buffers = self.buffers.clone();
1153 return right;
1156 }
1157
1158 let (left_root, right_root) = self.split(self.root, byte_offset);
1162
1163 self.root = left_root;
1167 self.last_mod_end = u32::MAX;
1168 self.last_tree_end = u32::MAX;
1169 self.undo_stack.clear();
1170 self.redo_stack.clear();
1171
1172 let mut right = Self::default();
1176 right.pieces = self.pieces.clone();
1177 right.buffers = self.buffers.clone();
1178 right.root = right_root;
1179
1180 right
1181 }
1182
1183 #[cfg(feature = "write")]
1184 pub fn from_reader<R: std::io::Read>(mut reader: R) -> std::io::Result<Self> {
1185 const CHUNK: usize = 64 * 1024;
1186
1187 let mut buf = [0u8; CHUNK];
1188 let mut text = String::new();
1189 let mut tail = 0usize;
1190
1191 loop {
1192 let n = reader.read(&mut buf[tail..])?;
1193
1194 if n == 0 {
1195 if tail > 0 {
1197 return Err(std::io::Error::new(
1198 std::io::ErrorKind::InvalidData,
1199 "stream ended with incomplete UTF-8 sequence",
1200 ));
1201 }
1202
1203 break;
1204 }
1205
1206 let filled = tail + n;
1207 let slice = &buf[..filled];
1208
1209 let valid_up_to = match str::from_utf8(slice) {
1213 Ok(_) => filled,
1214 Err(e) => {
1215 if e.error_len().is_some() {
1216 return Err(std::io::Error::new(
1217 std::io::ErrorKind::InvalidData,
1218 "stream did not contain valid UTF-8",
1219 ));
1220 }
1221 e.valid_up_to()
1222 }
1223 };
1224
1225 text.push_str(unsafe { std::str::from_utf8_unchecked(&slice[..valid_up_to]) });
1229
1230 tail = filled - valid_up_to;
1234 if tail > 0 {
1235 buf.copy_within(valid_up_to..filled, 0);
1236 }
1237 }
1238
1239 Ok(Self::from(text))
1240 }
1241}
1242
1243impl PieceTree {
1244 #[inline]
1246 #[must_use]
1247 pub fn take_snapshot(&self, current_cursor: u32) -> HistoryEntry {
1248 HistoryEntry {
1249 root: self.root,
1250 cursor_offset: current_cursor,
1251 }
1252 }
1253
1254 #[inline]
1257 #[must_use]
1258 pub fn snap_to(&mut self, snapshot: HistoryEntry, current_cursor: u32) -> u32 {
1259 if self.root == snapshot.root {
1260 return snapshot.cursor_offset;
1261 }
1262
1263 assert!(self.transaction_depth == 0, "Cannot snap_to during an active undo group");
1267
1268 self.undo_stack.push(HistoryEntry {
1272 root: self.root,
1273 cursor_offset: current_cursor,
1274 });
1275
1276 self.redo_stack.clear();
1280
1281 self.last_tree_end = u32::MAX;
1285 self.last_mod_end = u32::MAX;
1286
1287 self.root = snapshot.root;
1291
1292 snapshot.cursor_offset
1293 }
1294}
1295
1296impl PieceTree {
1297 #[inline]
1299 pub fn begin_undo_group(&mut self, cursor_offset: u32) {
1300 if self.transaction_depth == 0 {
1301 self.commit_head(cursor_offset);
1302 }
1303
1304 self.transaction_depth += 1;
1305 }
1306
1307 #[inline]
1309 pub fn end_undo_group(&mut self) {
1310 if self.transaction_depth > 0 {
1311 self.transaction_depth -= 1;
1312 }
1313 }
1314
1315 #[inline(always)]
1316 pub fn commit_head(&mut self, cursor_offset: u32) {
1317 if let Some(last) = self.undo_stack.last() {
1318 if last.root == self.root {
1319 return; }
1321 }
1322
1323 self.undo_stack.push(HistoryEntry { root: self.root, cursor_offset });
1324 self.redo_stack.clear();
1325 }
1326
1327 #[inline(always)]
1328 pub fn try_undo(&mut self, current_cursor: u32) -> Option<u32> {
1329 if self.transaction_depth > 0 {
1330 return None;
1331 }
1332
1333 if let Some(entry) = self.undo_stack.pop() {
1334 self.last_tree_end = u32::MAX;
1335 self.last_mod_end = u32::MAX;
1336
1337 self.redo_stack.push(HistoryEntry {
1338 root: self.root, cursor_offset: current_cursor
1339 });
1340 self.root = entry.root;
1341 return Some(entry.cursor_offset);
1342 }
1343
1344 None
1345 }
1346
1347 #[inline(always)]
1348 pub fn try_redo(&mut self, current_cursor: u32) -> Option<u32> {
1349 if let Some(entry) = self.redo_stack.pop() {
1350 self.last_tree_end = u32::MAX;
1351 self.last_mod_end = u32::MAX;
1352
1353 self.undo_stack.push(HistoryEntry {
1354 root: self.root, cursor_offset: current_cursor
1355 });
1356 self.root = entry.root;
1357 return Some(entry.cursor_offset);
1358 }
1359
1360 None
1361 }
1362
1363 #[inline(always)]
1364 #[must_use]
1365 pub fn total_length(&self) -> u32 {
1366 self.pieces.get(self.root).subtree_len
1367 }
1368
1369 #[inline(always)]
1370 pub fn apply_edits(&mut self, primary_cursor_offset: u32, edits: &mut [Edit]) {
1371 if edits.is_empty() { return }
1372
1373 self.begin_undo_group(primary_cursor_offset);
1374
1375 edits.sort_by_key(|b| core::cmp::Reverse(b.offset()));
1376 for edit in edits {
1377 match edit {
1378 Edit::Insert { offset, text } => self.insert_no_commit(*offset, text),
1379 Edit::Remove { offset, length } => self.remove_no_commit(*offset, *length),
1380 }
1381 }
1382
1383 self.end_undo_group();
1384 }
1385
1386 #[inline(always)]
1388 pub fn insert_char(&mut self, offset: u32, ch: char) {
1389 self.commit_head(offset);
1390 self.insert_char_no_commit(offset, ch);
1391 }
1392
1393 #[inline(always)]
1395 pub fn insert_char_no_commit(&mut self, offset: u32, ch: char) {
1396 let mut buf = [0; 4];
1397 self.insert_no_commit(offset, ch.encode_utf8(&mut buf));
1398 }
1399
1400 #[inline(always)]
1401 pub fn insert(&mut self, offset: u32, text: &str) {
1402 if text.is_empty() { return }
1403
1404 let auto_group = self.transaction_depth == 0;
1405 if auto_group {
1406 self.begin_undo_group(offset);
1407 }
1408
1409 self.insert_no_commit(offset, text);
1410
1411 if auto_group {
1412 self.end_undo_group();
1413 }
1414 }
1415
1416 #[inline(always)]
1417 pub fn remove_at(&mut self, offset: u32, length: u32) {
1418 if length == 0 || self.root == NIL { return }
1419
1420 let auto_group = self.transaction_depth == 0;
1421 if auto_group {
1422 self.begin_undo_group(offset);
1423 }
1424
1425 self.remove_no_commit(offset, length);
1426
1427 if auto_group {
1428 self.end_undo_group();
1429 }
1430 }
1431
1432 pub fn insert_no_commit(&mut self, offset: u32, text: &str) {
1433 let mod_offset = self.buffers.modifications_buffer.len() as u32;
1434 let start_line_in_buffer = self.buffers.modifications_newline_offsets.len() as u32;
1435
1436 let total_char_count_before = self.buffers.modifications_char_count;
1437 let mut total_char_count = total_char_count_before;
1438
1439 self.buffers.modifications_newline_offsets.reserve(text.len() / 20 + 1);
1440 self.buffers.modifications_char_checkpoints.reserve(text.len() / CHECKPOINT_INTERVAL as usize + 1);
1441
1442 let mut newline_count = 0;
1443 let mut char_count = 0;
1444 {
1445 let rem = total_char_count % CHECKPOINT_INTERVAL;
1446 let mut next_checkpoint = total_char_count + ((CHECKPOINT_INTERVAL - rem) % CHECKPOINT_INTERVAL);
1447
1448 if next_checkpoint == 0 {
1449 next_checkpoint = CHECKPOINT_INTERVAL;
1450 }
1451
1452 for (i, b) in text.bytes().enumerate() {
1456 if (b as i8) >= -0x40 {
1457 if total_char_count == next_checkpoint {
1458 self.buffers.modifications_char_checkpoints.push((total_char_count, mod_offset + i as u32));
1459 next_checkpoint += CHECKPOINT_INTERVAL;
1460 }
1461
1462 total_char_count += 1;
1463 char_count += 1;
1464 }
1465
1466 if b == b'\n' {
1467 self.buffers.modifications_newline_offsets.push(mod_offset + i as u32);
1468 newline_count += 1;
1469 }
1470 }
1471 }
1472
1473 self.buffers.modifications_char_count = total_char_count;
1474 self.buffers.modifications_buffer.push_str(text);
1475 let text_len = text.len() as u32;
1476
1477 let new_mod_end = mod_offset + text_len;
1478 let new_tree_end = offset + text_len;
1479
1480 if offset > 0
1484 && self.last_tree_end == offset
1485 && self.last_mod_end == mod_offset
1486 && let Some((prev_index, prev_rel)) = self.find_position(offset - 1, false)
1487 {
1488 let prev = self.pieces.get_piece(prev_index);
1489
1490 if prev.buffer == MOD_BUFFER && prev.byte_offset + prev.byte_length == mod_offset {
1494 let prev_start = (offset - 1) - prev_rel;
1495
1496 self.root = self.pieces.extend_piece(
1497 self.root,
1498 prev_start,
1499 text_len,
1500 char_count,
1501 newline_count
1502 );
1503
1504 self.last_mod_end = new_mod_end;
1505 self.last_tree_end = new_tree_end;
1506 return;
1507 }
1508 }
1509
1510 let new_piece = Piece {
1511 buffer: MOD_BUFFER,
1512 byte_offset: mod_offset,
1513 byte_length: text_len,
1514 newline_count,
1515 char_count,
1516 buffer_start_line: start_line_in_buffer,
1517 piece_start_char: total_char_count - char_count,
1518 };
1519
1520 if self.root == NIL {
1521 self.root = self.pieces.insert_node(self.root, new_piece, offset);
1522 } else {
1523 let (left, right) = self.split(self.root, offset);
1527
1528 self.root = self.pieces.join_with_middle(left, new_piece, right);
1532
1533 self.try_merge_at(offset);
1539
1540 self.try_merge_at(offset + text_len);
1542 }
1543
1544 self.last_mod_end = new_mod_end;
1545 self.last_tree_end = new_tree_end;
1546 }
1547
1548 pub fn remove_no_commit(&mut self, offset: u32, mut length: u32) {
1549 let total = self.total_length();
1550 if offset >= total { return; }
1551 if offset + length > total { length = total - offset; }
1552 if length == 0 { return }
1553
1554 let (left, remainder) = self.split(self.root, offset);
1558
1559 let (_deleted, right) = self.split(remainder, length);
1563
1564 self.root = self.concat(left, right);
1568
1569 self.try_merge_at(offset);
1573 }
1574
1575 #[inline]
1576 fn try_merge_at(&mut self, pos: u32) {
1577 if pos == 0 { return }
1578
1579 let Some((right_index, right_rel)) = self.find_position(pos, false) else { return };
1580
1581 if right_rel != 0 { return }
1582
1583 let right = self.pieces.get_piece(right_index);
1584 self.try_merge_right_with_left(pos, right);
1585 }
1586
1587 #[inline]
1589 fn try_merge_right_with_left(&mut self, right_start: u32, right: Piece) -> Option<(u32, Piece)> {
1590 if right_start == 0 { return None; }
1591 if right.buffer != MOD_BUFFER { return None; }
1592
1593 let (left_index, left_rel) = self.find_position(right_start - 1, false)?;
1594 let left = self.pieces.get_piece(left_index);
1595
1596 if left.buffer != MOD_BUFFER { return None; }
1597 if left.byte_offset + left.byte_length != right.byte_offset { return None; }
1598
1599 let left_start = (right_start - 1) - left_rel;
1600
1601 self.root = self.pieces.remove_node(self.root, left_start);
1602 self.root = self.pieces.remove_node(self.root, left_start);
1603
1604 let merged = Piece {
1605 buffer: MOD_BUFFER,
1606 byte_offset: left.byte_offset,
1607 byte_length: left.byte_length + right.byte_length,
1608 newline_count: left.newline_count + right.newline_count,
1609 char_count: left.char_count + right.char_count,
1610 buffer_start_line: left.buffer_start_line,
1611 piece_start_char: left.piece_start_char, };
1613 self.root = self.pieces.insert_node(self.root, merged, left_start);
1614 Some((left_start, merged))
1615 }
1616
1617 #[inline(always)]
1618 #[must_use]
1619 pub fn get_piece(&self, index: NodeRef) -> Piece {
1620 self.pieces.get_piece(index)
1621 }
1622
1623 #[inline]
1624 #[must_use]
1625 pub fn find_position(&self, offset: u32, prefer_left: bool) -> Option<(NodeRef, u32)> {
1626 let total = self.total_length();
1627 if offset > total { return None; }
1628
1629 if offset == total && total > 0 {
1630 let mut current = self.root;
1631 let mut last_valid = NIL;
1632 while current != NIL {
1633 last_valid = current;
1634 current = self.pieces.get(current).right;
1635 }
1636 let len = self.pieces.get_piece(last_valid).byte_length;
1637 return Some((last_valid, len));
1638 }
1639
1640 self.pieces.find_offset(self.root, offset, prefer_left)
1641 }
1642
1643 #[cfg(feature = "write")]
1644 #[inline]
1645 pub fn write_to<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
1646 if self.root == NIL {
1647 return Ok(());
1648 }
1649
1650 for (_, piece) in self.pieces() {
1651 let slice = self.buffers.get_slice(piece.buffer, piece.byte_offset, piece.byte_length);
1652 writer.write_all(slice.as_bytes())?;
1653 }
1654
1655 writer.flush()
1656 }
1657}
1658
1659impl PieceTree {
1660 #[inline]
1661 pub fn compact(&mut self) {
1662 #[inline(always)]
1663 fn copy_node(
1664 old_index: NodeRef, old_arena: &Pieces,
1665 new_arena: &mut Pieces, index_map: &mut [u32]
1666 ) -> NodeRef {
1667 if old_index == NIL { return NIL }
1668
1669 if index_map[old_index.index()] != 0 {
1670 return NodeRef::new(index_map[old_index.index()] as usize);
1671 }
1672
1673 let node = old_arena.get(old_index);
1674 let left_new = copy_node(node.left, old_arena, new_arena, index_map);
1675 let right_new = copy_node(node.right, old_arena, new_arena, index_map);
1676
1677 let new_index = NodeRef::new(new_arena.nodes.len());
1678 new_arena.nodes.push(Node {
1679 left: left_new,
1680 right: right_new,
1681 offset: node.offset,
1682 subtree_len: node.subtree_len,
1683 subtree_chars: node.subtree_chars,
1684 subtree_newlines: node.subtree_newlines,
1685 piece_start_char: node.piece_start_char,
1686 meta: node.meta,
1687 buffer_start_line: node.buffer_start_line
1688 });
1689
1690 index_map[old_index.index()] = new_index.index() as u32;
1691 new_index
1692 }
1693
1694 let mut new_pieces = Pieces::new();
1695
1696 self.scratch_index_map.clear();
1697 self.scratch_index_map.resize(self.pieces.nodes.len(), 0);
1698
1699 self.root = copy_node(self.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1700 for entry in &mut self.undo_stack {
1701 entry.root = copy_node(entry.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1702 }
1703 for entry in &mut self.redo_stack {
1704 entry.root = copy_node(entry.root, &self.pieces, &mut new_pieces, &mut self.scratch_index_map);
1705 }
1706
1707 self.pieces = new_pieces;
1708 }
1709
1710 #[inline]
1711 pub fn squash(&mut self) { if self.root == NIL { return }
1713
1714 let squashed_text = self.to_string(); let bytes = squashed_text.as_bytes();
1716 let length = squashed_text.len() as u32;
1717
1718 let mut offsets = Vec::with_capacity(bytes.len() / 40);
1719 let mut checkpoints = Vec::with_capacity(bytes.len() / 256);
1720
1721 let (char_count, newline_count) =
1722 count_chars_and_newlines_with_offsets_and_checkpoints(
1723 squashed_text.as_bytes(),
1724 &mut offsets,
1725 &mut checkpoints
1726 );
1727
1728 self.buffers = Buffers::new();
1729 let buffer = self.buffers.original_buffers.push(OriginalBuffer {
1730 newline_offsets: offsets.into(),
1731 char_checkpoints: checkpoints.into(),
1732 text: squashed_text.into()
1733 });
1734 self.pieces = Pieces::new();
1735
1736 let piece = Piece {
1737 byte_length: length, newline_count, char_count,
1738 buffer, byte_offset: 0,
1739 buffer_start_line: 0, piece_start_char: 0
1740 };
1741 self.root = self.pieces.insert_node(NIL, piece, 0);
1742
1743 self.undo_stack.clear();
1744 self.redo_stack.clear();
1745 }
1746}
1747
1748#[derive(Debug, Clone, Copy)]
1749pub struct MemoryUsage {
1750 pub node_arena: u32,
1751 pub mod_buffer: u32,
1752 pub original_buffers: u32,
1753 pub history: u32,
1754}
1755
1756impl MemoryUsage {
1757 #[inline(always)]
1758 #[must_use]
1759 pub const fn total(&self) -> u32 {
1760 self.node_arena + self.mod_buffer + self.original_buffers + self.history
1761 }
1762
1763 #[inline(always)]
1765 #[must_use]
1766 pub const fn overhead(&self) -> u32 {
1767 self.node_arena + self.history
1768 }
1769}
1770
1771impl PieceTree {
1772 #[inline(always)]
1775 #[must_use]
1776 pub fn node_arena_bytes(&self) -> u32 {
1777 (self.pieces.nodes.len() * size_of::<Node>()) as _
1778 }
1779
1780 #[inline(always)]
1782 #[must_use]
1783 pub fn mod_buffer_bytes(&self) -> u32 {
1784 self.buffers.modifications_buffer.len() as u32 +
1785 (self.buffers.modifications_char_checkpoints.len() * size_of::<(u32, u32)>()) as u32 +
1786 (self.buffers.modifications_newline_offsets.len() * size_of::<u32>()) as u32
1787 }
1788
1789 #[inline(always)]
1791 #[must_use]
1792 pub fn original_buffers_bytes(&self) -> u32 {
1793 self.buffers.original_buffers.values().map(|s| {
1794 s.len() +
1795 s.char_checkpoints.len() * size_of::<(u32, u32)>() +
1796 s.newline_offsets.len() * size_of::<u32>()
1797 }).sum::<usize>() as _
1798 }
1799
1800 #[inline(always)]
1802 #[must_use]
1803 pub fn history_bytes(&self) -> u32 {
1804 ((self.undo_stack.len() + self.redo_stack.len()) * size_of::<HistoryEntry>()) as _
1805 }
1806
1807 #[inline(always)]
1809 #[must_use]
1810 pub fn node_count(&self) -> u32 {
1811 self.pieces.nodes.len() as _
1812 }
1813
1814 #[inline(always)]
1816 #[must_use]
1817 pub fn memory_usage(&self) -> MemoryUsage {
1818 MemoryUsage {
1819 node_arena: self.node_arena_bytes(),
1820 mod_buffer: self.mod_buffer_bytes(),
1821 original_buffers: self.original_buffers_bytes(),
1822 history: self.history_bytes(),
1823 }
1824 }
1825}
1826
1827#[derive(Debug)]
1828pub struct LinesIter<'a> {
1829 tree: &'a PieceTree,
1830 current_line: u32,
1831 total_lines: u32,
1832}
1833
1834impl Iterator for LinesIter<'_> {
1835 type Item = String;
1836
1837 fn next(&mut self) -> Option<Self::Item> {
1838 if self.current_line >= self.total_lines { return None }
1839
1840 let line = self.tree.get_line_content_allocating(self.current_line)?;
1841 self.current_line += 1;
1842 Some(line)
1843 }
1844}
1845
1846#[derive(Debug)]
1848pub struct ChunkIter<'a> {
1849 tree: &'a PieceTree,
1850 pieces: PieceTreeIter<'a>,
1851 start: u32,
1853 end: u32,
1854 piece_start: u32,
1856}
1857
1858impl<'a> ChunkIter<'a> {
1859 #[inline]
1860 #[must_use]
1861 pub fn new(tree: &'a PieceTree, start: u32, end: u32) -> Self {
1862 Self {
1863 tree,
1864 pieces: PieceTreeIter::new(&tree.pieces, tree.root),
1865 start,
1866 end,
1867 piece_start: 0,
1868 }
1869 }
1870
1871 #[inline]
1873 #[must_use]
1874 pub fn len_chars(&self) -> u32 {
1875 let start_char = self.tree.try_byte_to_char(self.start).unwrap_or(0);
1876 let end_char = self.tree.try_byte_to_char(self.end).unwrap_or_else(|| self.tree.len_chars());
1877 end_char.saturating_sub(start_char)
1878 }
1879
1880 #[inline]
1882 #[must_use]
1883 pub fn len_bytes(&self) -> u32 {
1884 self.end.saturating_sub(self.start)
1885 }
1886}
1887
1888impl<'a> Iterator for ChunkIter<'a> {
1889 type Item = &'a str;
1890
1891 #[inline]
1892 fn next(&mut self) -> Option<&'a str> {
1893 loop {
1894 let (_, p) = self.pieces.next()?;
1895 let piece_end = self.piece_start + p.byte_length;
1896
1897 if piece_end <= self.start {
1899 self.piece_start = piece_end;
1900 continue;
1901 }
1902 if self.piece_start >= self.end {
1904 return None;
1905 }
1906
1907 let slice_start = self.start.saturating_sub(self.piece_start);
1908 let slice_end = (self.end - self.piece_start).min(p.byte_length);
1909
1910 self.piece_start = piece_end;
1911
1912 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset + slice_start, slice_end - slice_start);
1913 if text.is_empty() { continue; }
1914 return Some(text);
1915 }
1916 }
1917}
1918
1919#[derive(Debug, Clone)]
1921pub struct SliceLines<'a> {
1922 slice: TreeSlice<'a>,
1923 current_abs_line: u32,
1924 end_abs_line: u32,
1925 yielded_all: bool,
1926}
1927
1928impl<'a> Iterator for SliceLines<'a> {
1929 type Item = TreeSlice<'a>;
1930
1931 #[inline]
1932 fn next(&mut self) -> Option<Self::Item> {
1933 if self.yielded_all { return None; }
1934
1935 let line_start = self.slice.tree.try_line_to_byte(self.current_abs_line).unwrap_or(self.slice.start);
1937
1938 if self.current_abs_line >= self.end_abs_line {
1942 self.yielded_all = true;
1943
1944 let start_byte = line_start.max(self.slice.start).min(self.slice.end);
1946
1947 return Some(TreeSlice {
1948 tree: self.slice.tree,
1949 start: start_byte,
1950 end: self.slice.end,
1951 });
1952 }
1953
1954 let next_line_start = self.slice.tree.try_line_to_byte(self.current_abs_line + 1).unwrap_or(self.slice.end);
1956
1957 let start_byte = line_start.max(self.slice.start).min(self.slice.end);
1959 let end_byte = next_line_start.min(self.slice.end);
1960
1961 self.current_abs_line += 1;
1962
1963 Some(TreeSlice {
1964 tree: self.slice.tree,
1965 start: start_byte,
1966 end: end_byte,
1967 })
1968 }
1969}
1970
1971#[derive(Debug)]
1972pub struct SliceCharsRev<'a> {
1973 walker: ReverseTreeWalker<'a>,
1974 current_byte: u32,
1975 start_byte: u32,
1976}
1977
1978impl<'a> Iterator for SliceCharsRev<'a> {
1979 type Item = char;
1980
1981 #[inline]
1982 fn next(&mut self) -> Option<char> {
1983 if self.current_byte <= self.start_byte {
1985 return None;
1986 }
1987
1988 let c = self.walker.next()?;
1989
1990 self.current_byte = self.current_byte.saturating_sub(c.len_utf8() as u32);
1992
1993 if self.current_byte < self.start_byte {
1996 return None;
1997 }
1998
1999 Some(c)
2000 }
2001}
2002
2003impl core::fmt::Display for SliceCharsRev<'_> {
2004 #[inline]
2005 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2006 let mut chars = Vec::new();
2007 let mut temp_walker = ReverseTreeWalker::new_at(self.walker.tree, self.current_byte);
2008
2009 let mut temp_byte = self.current_byte;
2010 while temp_byte > self.start_byte {
2011 let Some(c) = temp_walker.next() else { break };
2012 let new_byte = temp_byte.saturating_sub(c.len_utf8() as u32);
2013 if new_byte < self.start_byte { break; }
2014 temp_byte = new_byte;
2015 chars.push(c);
2016 }
2017
2018 chars.reverse();
2019
2020 let mut buf = Vec::with_capacity(chars.iter().map(|c| c.len_utf8()).sum());
2021 let mut tmp = [0u8; 4];
2022 for c in &chars {
2023 buf.extend_from_slice(c.encode_utf8(&mut tmp).as_bytes());
2024 }
2025
2026 f.write_str(unsafe { core::str::from_utf8_unchecked(&buf) })
2027 }
2028}
2029
2030#[derive(Debug)]
2032pub struct SliceChars<'a> {
2033 walker: TreeWalker<'a>,
2034 byte_end: u32,
2035}
2036
2037impl Iterator for SliceChars<'_> {
2038 type Item = char;
2039 #[inline]
2040 fn next(&mut self) -> Option<char> {
2041 if self.walker.offset >= self.byte_end { return None; }
2042 self.walker.next()
2043 }
2044}
2045
2046impl core::fmt::Display for SliceChars<'_> {
2047 #[inline]
2048 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2049 let current_offset = self.walker.offset;
2051
2052 let mut temp_walker = TreeWalker::<32>::new(self.walker.tree);
2054 temp_walker.seek(current_offset);
2055
2056 while temp_walker.offset < self.byte_end {
2057 let chunk = temp_walker.current_str.as_str();
2058 if chunk.is_empty() {
2059 if temp_walker.stack.is_empty() { break; }
2060 temp_walker.populate_chars();
2061 continue;
2062 }
2063
2064 let remaining = (self.byte_end - temp_walker.offset) as usize;
2066 let chunk = &chunk[..remaining.min(chunk.len())];
2067 f.write_str(chunk)?;
2068 temp_walker.offset += chunk.len() as u32;
2069 temp_walker.current_str = "".chars();
2070 temp_walker.populate_chars();
2071 }
2072
2073 Ok(())
2074 }
2075}
2076
2077#[derive(Debug, Clone, Copy)]
2080pub struct TreeSlice<'a> {
2081 tree: &'a PieceTree,
2082 start: u32, end: u32, }
2085
2086impl PartialEq<&str> for TreeSlice<'_> {
2087 #[inline]
2088 fn eq(&self, other: &&str) -> bool {
2089 let mut remaining = other.as_bytes();
2090
2091 for chunk in self.chunks() {
2092 let chunk_bytes = chunk.as_bytes();
2093
2094 if remaining.len() < chunk_bytes.len() {
2096 return false;
2097 }
2098
2099 if !remaining.starts_with(chunk_bytes) {
2101 return false;
2102 }
2103
2104 remaining = &remaining[chunk_bytes.len()..];
2105 }
2106
2107 remaining.is_empty()
2109 }
2110}
2111
2112impl PartialEq<str> for TreeSlice<'_> {
2113 #[inline]
2114 fn eq(&self, other: &str) -> bool {
2115 self == &other
2116 }
2117}
2118
2119impl core::fmt::Display for TreeSlice<'_> {
2120 #[inline(always)]
2121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2122 for chunk in self.chunks() {
2123 f.write_str(chunk)?;
2124 }
2125 Ok(())
2126 }
2127}
2128
2129impl<'a> TreeSlice<'a> {
2131 #[inline]
2132 pub fn chunks(self) -> ChunkIter<'a> {
2133 ChunkIter::new(self.tree, self.start, self.end)
2134 }
2135
2136 #[inline]
2137 pub fn bytes(self) -> impl Iterator<Item = u8> + 'a {
2138 self.chunks().flat_map(|chunk| chunk.bytes())
2139 }
2140
2141 #[inline]
2142 pub fn chars(self) -> impl Iterator<Item = char> + 'a {
2143 self.chunks().flat_map(|chunk| chunk.chars())
2144 }
2145
2146 #[inline]
2147 pub fn chars_rev(self) -> SliceCharsRev<'a> {
2148 SliceCharsRev {
2149 walker: ReverseTreeWalker::new_at(self.tree, self.end),
2150 current_byte: self.end,
2151 start_byte: self.start,
2152 }
2153 }
2154
2155 #[inline]
2156 pub fn lines(self) -> SliceLines<'a> {
2157 let start_line = self.tree.byte_to_line(self.start);
2159 let end_line = self.tree.byte_to_line(self.end);
2160
2161 SliceLines {
2162 slice: self,
2163 current_abs_line: start_line,
2164 end_abs_line: end_line,
2165 yielded_all: false,
2166 }
2167 }
2168
2169 #[inline]
2170 pub fn lines_at(self, line_idx: u32) -> SliceLines<'a> {
2171 let start_line = self.tree.byte_to_line(self.start);
2172 let end_line = self.tree.byte_to_line(self.end);
2173
2174 let target_line = (start_line + line_idx).min(end_line);
2175
2176 SliceLines {
2177 slice: self,
2178 current_abs_line: target_line,
2179 end_abs_line: end_line,
2180 yielded_all: false,
2181 }
2182 }
2183
2184 #[inline]
2185 pub fn chunks_at_byte(self, byte_idx: u32) -> ChunkIter<'a> {
2186 let safe_idx = byte_idx.min(self.len_bytes());
2187 ChunkIter::new(self.tree, self.start + safe_idx, self.end)
2188 }
2189
2190 #[inline]
2191 pub fn bytes_at(self, byte_idx: u32) -> impl Iterator<Item = u8> + 'a {
2192 self.chunks_at_byte(byte_idx).flat_map(|chunk| chunk.bytes())
2193 }
2194
2195 #[inline]
2196 pub fn chars_at(self, char_idx: u32) -> impl Iterator<Item = char> + 'a {
2197 let safe_idx = char_idx.min(self.len_chars());
2198 let byte_offset = self.try_char_to_byte(safe_idx).unwrap_or(self.len_bytes());
2199 self.chunks_at_byte(byte_offset).flat_map(|chunk| chunk.chars())
2200 }
2201}
2202
2203impl PieceTree {
2205 #[inline]
2206 pub fn slice_whole(&self) -> TreeSlice<'_> {
2207 self.slice(0..self.len_bytes())
2208 }
2209
2210 #[inline]
2211 pub fn chunks(&self) -> ChunkIter<'_> { self.slice_whole().chunks() }
2212
2213 #[inline]
2214 pub fn bytes(&self) -> impl Iterator<Item = u8> + '_ { self.slice_whole().bytes() }
2215
2216 #[inline]
2217 pub fn chars(&self) -> impl Iterator<Item = char> + '_ { self.slice_whole().chars() }
2218
2219 #[inline]
2220 pub fn lines(&self) -> SliceLines<'_> { self.slice_whole().lines() }
2221
2222 #[inline(always)]
2223 #[must_use]
2224 pub fn chars_rev(&self) -> ReverseTreeWalker<'_> { ReverseTreeWalker::new(self) }
2225
2226 #[inline(always)]
2227 #[must_use]
2228 pub fn chars_at_rev(&self, char_idx: u32) -> ReverseTreeWalker<'_> { ReverseTreeWalker::new_at(self, char_idx) }
2229
2230 #[inline]
2231 pub fn chunks_at_byte(&self, byte_idx: u32) -> ChunkIter<'_> {
2232 self.slice_whole().chunks_at_byte(byte_idx)
2233 }
2234
2235 #[inline]
2236 pub fn bytes_at(&self, byte_idx: u32) -> impl Iterator<Item = u8> + '_ {
2237 self.slice_whole().bytes_at(byte_idx)
2238 }
2239
2240 #[inline]
2241 pub fn chars_at(&self, char_idx: u32) -> impl Iterator<Item = char> + '_ {
2242 self.slice_whole().chars_at(char_idx)
2243 }
2244
2245 #[inline]
2246 pub fn lines_at(&self, line_idx: u32) -> SliceLines<'_> {
2247 self.slice_whole().lines_at(line_idx)
2248 }
2249}
2250
2251impl<'a> TreeSlice<'a> {
2252 #[inline(always)]
2253 #[must_use]
2254 pub fn new(tree: &'a PieceTree, start: u32, end: u32) -> Self {
2255 let end = end.min(tree.len_bytes());
2256 debug_assert!(start <= end);
2257 Self { tree, start, end }
2258 }
2259
2260 #[inline(always)]
2261 #[must_use]
2262 pub fn len_bytes(&self) -> u32 { self.end - self.start }
2263
2264 #[inline(always)]
2265 #[must_use]
2266 pub fn is_empty(&self) -> bool { self.start == self.end }
2267
2268 #[inline(always)]
2269 #[must_use]
2270 pub fn len_chars(&self) -> u32 {
2271 let a = self.tree.try_byte_to_char(self.start).unwrap_or(0);
2272 let b = self.tree.try_byte_to_char(self.end).unwrap_or_else(|| self.tree.len_chars());
2273 b - a
2274 }
2275
2276 #[inline]
2277 #[must_use]
2278 pub fn len_lines(&self) -> u32 {
2279 let start_line = self.tree.try_byte_to_line(self.start).unwrap_or(0);
2280 let end_line = self.tree.try_byte_to_line(self.end).unwrap_or_else(|| self.tree.len_lines() - 1);
2281 end_line - start_line + 1
2282 }
2283
2284 #[must_use]
2285 pub fn chunk_at_byte(&self, offset: u32) -> &[u8] {
2286 if offset >= self.len_bytes() { return &[] }
2287
2288 let abs_byte = self.start + offset;
2289 let chunk = self.tree.chunk_at_byte(abs_byte).0;
2290
2291 let max_valid_len = (self.end - abs_byte) as usize;
2293 let bounded_len = chunk.len().min(max_valid_len);
2294
2295 &chunk[..bounded_len]
2296 }
2297
2298 #[inline]
2299 #[must_use]
2300 pub fn chunk_at_char(&self, char_offset: u32) -> &[u8] {
2301 if char_offset >= self.len_chars() { return &[] }
2302
2303 let Some(base_char) = self.tree.try_byte_to_char(self.start) else {
2304 return &[];
2305 };
2306 let abs_char = base_char + char_offset;
2307
2308 let chunk = self.tree.chunk_at_char(abs_char).0;
2309
2310 let Some(abs_byte) = self.tree.try_char_to_byte(abs_char) else {
2312 return &[];
2313 };
2314
2315 let max_valid_len = (self.end - abs_byte) as usize;
2316 let bounded_len = chunk.len().min(max_valid_len);
2317
2318 &chunk[..bounded_len]
2319 }
2320
2321 #[inline]
2322 #[must_use]
2323 pub fn chunk_at_line_break(&self, break_index: u32) -> &[u8] {
2324 let Some((base_line, _)) = self.tree.try_byte_to_line_col(self.start) else {
2325 return &[];
2326 };
2327
2328 let abs_break_index = base_line + break_index;
2329
2330 let Some(abs_byte) = self.tree.try_line_break_to_byte(abs_break_index) else {
2331 return &[];
2332 };
2333
2334 if abs_byte < self.start || abs_byte >= self.end {
2336 return &[];
2337 }
2338
2339 let chunk = self.tree.chunk_at_byte(abs_byte).0;
2340
2341 let max_valid_len = (self.end - abs_byte) as usize;
2343 let bounded_len = chunk.len().min(max_valid_len);
2344
2345 &chunk[..bounded_len]
2346 }
2347
2348 #[inline(always)]
2350 #[must_use]
2351 pub fn byte(&self, offset: u32) -> u8 {
2352 self.try_byte(offset).unwrap()
2353 }
2354
2355 #[inline(always)]
2357 #[must_use]
2358 pub fn try_byte(&self, offset: u32) -> Option<u8> {
2359 if offset >= self.len_bytes() { return None; }
2360 self.tree.try_byte(self.start + offset)
2361 }
2362
2363 #[inline(always)]
2365 #[must_use]
2366 pub fn char(&self, char_index: u32) -> char {
2367 self.try_char(char_index).unwrap()
2368 }
2369
2370 #[inline(always)]
2372 #[must_use]
2373 pub fn try_char(&self, char_index: u32) -> Option<char> {
2374 if char_index >= self.len_chars() { return None; }
2375 let abs_char = self.tree.try_byte_to_char(self.start)? + char_index;
2376 self.tree.try_char(abs_char)
2377 }
2378
2379 #[inline(always)]
2380 #[must_use]
2381 pub fn line(&self, line: u32) -> ChunkIter<'a> {
2382 self.try_line(line).unwrap()
2383 }
2384
2385 #[inline(always)]
2386 #[must_use]
2387 pub fn try_line(&self, line: u32) -> Option<ChunkIter<'a>> {
2388 let (abs_start, abs_end) = self.abs_line_range(line)?;
2389 Some(ChunkIter::new(self.tree, abs_start, abs_end))
2391 }
2392
2393 #[inline(always)]
2395 #[must_use]
2396 pub fn slice<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'a> {
2397 let s = match range.start_bound() {
2398 Bound::Included(&n) => n,
2399 Bound::Excluded(&n) => n + 1,
2400 Bound::Unbounded => 0,
2401 };
2402 let e = match range.end_bound() {
2403 Bound::Included(&n) => n + 1,
2404 Bound::Excluded(&n) => n,
2405 Bound::Unbounded => self.len_bytes(),
2406 };
2407 TreeSlice::new(self.tree, self.start + s, self.start + e)
2408 }
2409
2410 #[inline(always)]
2411 #[must_use]
2412 pub fn byte_to_char(&self, byte_offset: u32) -> u32 {
2413 self.try_byte_to_char(byte_offset).unwrap()
2414 }
2415
2416 #[inline(always)]
2417 #[must_use]
2418 pub fn try_byte_to_char(&self, byte_offset: u32) -> Option<u32> {
2419 let base = self.tree.try_byte_to_char(self.start)?;
2420 let abs = self.tree.try_byte_to_char(self.start + byte_offset)?;
2421 Some(abs - base)
2422 }
2423
2424 #[inline(always)]
2425 #[must_use]
2426 pub fn char_to_byte(&self, char_index: u32) -> u32 {
2427 self.try_char_to_byte(char_index).unwrap()
2428 }
2429
2430 #[inline(always)]
2431 #[must_use]
2432 pub fn try_char_to_byte(&self, char_index: u32) -> Option<u32> {
2433 let base_char = self.tree.try_byte_to_char(self.start)?;
2434 let abs_byte = self.tree.try_char_to_byte(base_char + char_index)?;
2435 Some(abs_byte - self.start)
2436 }
2437
2438 #[inline(always)]
2439 #[must_use]
2440 pub fn byte_to_line(&self, byte_offset: u32) -> u32 {
2441 self.try_byte_to_line(byte_offset).unwrap()
2442 }
2443
2444 #[inline(always)]
2445 #[must_use]
2446 pub fn try_byte_to_line(&self, byte_offset: u32) -> Option<u32> {
2447 let (abs_line, _) = self.tree.try_byte_to_line_col(self.start + byte_offset)?;
2448 let base_line = self.tree.try_byte_to_line_col(self.start).map(|(l, _)| l)?;
2449 Some(abs_line - base_line)
2450 }
2451
2452 #[inline(always)]
2453 #[must_use]
2454 pub fn line_to_byte(&self, line: u32) -> u32 {
2455 self.try_line_to_byte(line).unwrap()
2456 }
2457
2458 #[inline(always)]
2459 #[must_use]
2460 pub fn try_line_to_byte(&self, line: u32) -> Option<u32> {
2461 let (abs_start, _) = self.abs_line_range(line)?;
2462 Some(abs_start - self.start)
2463 }
2464
2465 #[inline]
2466 #[must_use]
2467 pub fn abs_line_range(&self, rel_line: u32) -> Option<(u32, u32)> {
2468 let base_line = self.tree.try_byte_to_line_col(self.start).map(|(l, _)| l)?;
2469 let abs_line = base_line + rel_line;
2470
2471 let line_start = self.tree.try_line_to_byte(abs_line)?;
2472 let line_end = self.tree.try_line_to_byte(abs_line + 1)
2473 .unwrap_or_else(|| self.tree.len_bytes());
2474
2475 let s = line_start.max(self.start);
2479 let e = line_end.min(self.end);
2480 if s > e { return None; }
2481
2482 Some((s, e))
2483 }
2484}
2485
2486impl PieceTree {
2488 #[inline]
2489 pub fn slice<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'_> {
2490 let s = match range.start_bound() {
2491 Bound::Included(&n) => n,
2492 Bound::Excluded(&n) => n + 1,
2493 Bound::Unbounded => 0,
2494 };
2495 let e = match range.end_bound() {
2496 Bound::Included(&n) => n + 1,
2497 Bound::Excluded(&n) => n,
2498 Bound::Unbounded => self.len_bytes(),
2499 };
2500 TreeSlice::new(self, s, e)
2501 }
2502
2503 #[inline]
2505 pub fn slice_chars_range<R: RangeBounds<u32>>(&self, range: R) -> TreeSlice<'_> {
2506 let sc = match range.start_bound() {
2507 Bound::Included(&n) => n,
2508 Bound::Excluded(&n) => n + 1,
2509 Bound::Unbounded => 0,
2510 };
2511 let ec = match range.end_bound() {
2512 Bound::Included(&n) => n + 1,
2513 Bound::Excluded(&n) => n,
2514 Bound::Unbounded => self.len_chars(),
2515 };
2516 let s = self.try_char_to_byte(sc).unwrap_or(0);
2517 let e = self.try_char_to_byte(ec).unwrap_or_else(|| self.len_bytes());
2518 TreeSlice::new(self, s, e)
2519 }
2520}
2521
2522impl PieceTree {
2523 #[inline]
2527 #[must_use]
2528 pub fn read_largest_contigous_chunk_at_byte(&self, offset: u32) -> (&[u8], u32) {
2529 let total = self.total_length();
2530 if offset >= total {
2531 return (&[], offset);
2532 }
2533
2534 let mut current = self.root;
2535 let mut current_offset = offset;
2536 let mut doc_offset = 0u32;
2537
2538 while current != NIL {
2539 let node = self.pieces.get(current);
2540 let p = self.pieces.get_piece(current);
2541 let left_len = self.pieces.get(node.left).subtree_len;
2542 let piece_len = p.byte_length;
2543
2544 if current_offset < left_len {
2545 current = node.left;
2546
2547 } else if current_offset < left_len + piece_len {
2548 let rel_offset = current_offset - left_len;
2553 let piece_doc_start = doc_offset + left_len;
2554
2555 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2556
2557 return (&text.as_bytes()[rel_offset as usize..], piece_doc_start);
2558
2559 } else {
2560 doc_offset += left_len + piece_len;
2561 current_offset -= left_len + piece_len;
2562 current = node.right;
2563 }
2564 }
2565
2566 (&[], offset)
2567 }
2568
2569 #[inline]
2570 #[must_use]
2571 pub fn chunk_at_byte(&self, offset: u32) -> (&[u8], u32) {
2572 self.read_largest_contigous_chunk_at_byte(offset)
2573 }
2574
2575 #[inline]
2576 #[must_use]
2577 pub fn chunk_at_char(&self, char_index: u32) -> (&[u8], u32) {
2578 let Some(offset) = self.try_char_to_byte(char_index) else { return (&[], 0) };
2579 self.chunk_at_byte(offset)
2580 }
2581
2582 #[inline]
2583 #[must_use]
2584 pub fn chunk_at_line_break(&self, break_index: u32) -> (&[u8], u32) {
2585 let Some(offset) = self.try_line_break_to_byte(break_index) else { return (&[], 0) };
2586 self.chunk_at_byte(offset)
2587 }
2588
2589 #[inline]
2590 #[must_use]
2591 pub fn line_break_to_byte(&self, break_index: u32) -> u32 {
2592 self.try_line_break_to_byte(break_index).unwrap()
2593 }
2594
2595 #[inline]
2596 #[must_use]
2597 pub fn try_line_break_to_byte(&self, break_index: u32) -> Option<u32> {
2598 let total_newlines = self.pieces.get(self.root).subtree_newlines;
2601 if break_index >= total_newlines { return None; }
2602
2603 let mut current = self.root;
2604 let mut current_offset = 0;
2605 let mut current_newlines = 0;
2606
2607 while current != NIL {
2608 let node = self.pieces.get(current);
2609 let p = self.pieces.get_piece(current);
2610 let left_newlines = self.pieces.get(node.left).subtree_newlines;
2611 let left_len = self.pieces.get(node.left).subtree_len;
2612 let piece_newlines = p.newline_count;
2613
2614 if break_index < current_newlines + left_newlines {
2615 current = node.left;
2619
2620 } else if break_index < current_newlines + left_newlines + piece_newlines {
2621 let rel_break = break_index - (current_newlines + left_newlines);
2625 let absolute_newline_index = p.buffer_start_line + rel_break;
2626
2627 let absolute_byte_offset = if p.buffer == MOD_BUFFER {
2628 self.buffers.modifications_newline_offsets[absolute_newline_index as usize]
2629 } else {
2630 self.buffers.original_buffers[p.buffer].newline_offsets[absolute_newline_index as usize]
2631 };
2632
2633 let local_piece_offset = absolute_byte_offset - p.byte_offset;
2646 return Some(current_offset + left_len + local_piece_offset);
2647
2648 } else {
2649 current_newlines += left_newlines + piece_newlines;
2650 current_offset += left_len + p.byte_length;
2651 current = node.right;
2652 }
2653 }
2654
2655 None
2656 }
2657
2658 #[inline]
2659 #[must_use]
2660 pub fn line_to_byte(&self, target_line: u32) -> u32 {
2661 self.try_line_to_byte(target_line).unwrap()
2662 }
2663
2664 #[inline]
2665 #[must_use]
2666 pub fn try_line_to_byte(&self, target_line: u32) -> Option<u32> {
2667 if target_line == 0 { return Some(0) }
2668 let mut current = self.root;
2669 let mut current_offset = 0;
2670 let mut current_line = 0;
2671 while current != NIL {
2672 let node = self.pieces.get(current);
2673 let p = self.pieces.get_piece(current);
2674 let left_newlines = self.pieces.get(node.left).subtree_newlines;
2675 let left_len = self.pieces.get(node.left).subtree_len;
2676 let piece_newlines = p.newline_count;
2677 let piece_len = p.byte_length;
2678
2679 if target_line <= current_line + left_newlines {
2680 current = node.left;
2684
2685 } else if target_line <= current_line + left_newlines + piece_newlines {
2686 current_line += left_newlines;
2691 current_offset += left_len;
2692
2693 let rel_line = target_line - current_line; let absolute_newline_index = p.buffer_start_line + rel_line - 1;
2695 let absolute_byte_offset = if p.buffer == MOD_BUFFER {
2696 self.buffers.modifications_newline_offsets[absolute_newline_index as usize]
2697 } else {
2698 self.buffers.original_buffers[p.buffer].newline_offsets[absolute_newline_index as usize]
2699 };
2700
2701 let local_piece_offset = absolute_byte_offset - p.byte_offset + 1;
2702 return Some(current_offset + local_piece_offset);
2703
2704 } else {
2705 current_line += left_newlines + piece_newlines;
2706 current_offset += left_len + piece_len;
2707 current = node.right;
2708 }
2709 }
2710
2711 None
2712 }
2713
2714 #[inline]
2715 #[must_use]
2716 pub fn char_to_byte(&self, char_index: u32) -> u32 {
2717 self.try_char_to_byte(char_index).unwrap()
2718 }
2719
2720 #[inline]
2721 #[must_use]
2722 pub fn try_char_to_byte(&self, char_index: u32) -> Option<u32> {
2723 let total_chars = self.len_chars();
2724 if char_index > total_chars { return None; }
2725 if char_index == total_chars { return Some(self.len_bytes()); }
2726
2727 let mut current = self.root;
2728 let mut current_byte = 0;
2729 let mut current_char = 0;
2730
2731 while current != NIL {
2732 let node = self.pieces.get(current);
2733 let left_node = self.pieces.get(node.left);
2734
2735 let left_chars = left_node.subtree_chars;
2736 let left_bytes = left_node.subtree_len;
2737
2738 let p = self.pieces.get_piece(current);
2739 let piece_chars = p.char_count;
2740
2741 if char_index < current_char + left_chars {
2742 current = node.left;
2743
2744 } else if char_index < current_char + left_chars + piece_chars {
2745 let rel_char = char_index - (current_char + left_chars);
2752 let absolute_target_byte =
2753 self.buffers.char_to_byte_absolute(p.buffer, p.piece_start_char + rel_char);
2754
2755 return Some(current_byte + left_bytes + (absolute_target_byte - p.byte_offset));
2756
2757 } else {
2758 current_char += left_chars + piece_chars;
2759 current_byte += left_bytes + p.byte_length;
2760 current = node.right;
2761 }
2762 }
2763
2764 None
2765 }
2766
2767 #[inline]
2768 #[must_use]
2769 pub fn byte_to_char(&self, byte_offset: u32) -> u32 {
2770 self.try_byte_to_char(byte_offset).unwrap()
2771 }
2772
2773 #[inline]
2774 #[must_use]
2775 pub fn try_byte_to_char(&self, byte_offset: u32) -> Option<u32> {
2776 let total_bytes = self.len_bytes();
2777 if byte_offset > total_bytes { return None; }
2778 if byte_offset == total_bytes { return Some(self.len_chars()); }
2779
2780 let mut current = self.root;
2781 let mut current_byte = 0;
2782 let mut current_char = 0;
2783
2784 while current != NIL {
2785 let node = self.pieces.get(current);
2786 let left_node = self.pieces.get(node.left);
2787
2788 let left_bytes = left_node.subtree_len;
2789 let left_chars = left_node.subtree_chars;
2790
2791 let p = self.pieces.get_piece(current);
2792 let piece_bytes = p.byte_length;
2793
2794 if byte_offset < current_byte + left_bytes {
2795 current = node.left;
2796
2797 } else if byte_offset < current_byte + left_bytes + piece_bytes {
2798 let rel_byte = byte_offset - (current_byte + left_bytes);
2803 let absolute_target_char =
2804 self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2805
2806 return Some(current_char + left_chars + (absolute_target_char - p.piece_start_char));
2807
2808 } else {
2809 current_byte += left_bytes + piece_bytes;
2810 current_char += left_chars + p.char_count;
2811 current = node.right;
2812 }
2813 }
2814
2815 None
2816 }
2817
2818 #[inline]
2819 #[must_use]
2820 pub fn byte_to_line(&self, offset: u32) -> u32 {
2821 self.try_byte_to_line(offset).unwrap()
2822 }
2823
2824 #[inline]
2825 #[must_use]
2826 pub fn try_byte_to_line(&self, offset: u32) -> Option<u32> {
2827 self.try_byte_to_line_col(offset).map(|(l, _)| l)
2828 }
2829
2830 #[inline]
2831 #[must_use]
2832 pub fn byte_to_line_col(&self, offset: u32) -> (u32, u32) {
2833 self.try_byte_to_line_col(offset).unwrap()
2834 }
2835
2836 #[inline]
2837 #[must_use]
2838 pub fn try_byte_to_line_col(&self, offset: u32) -> Option<(u32, u32)> {
2839 let total_bytes = self.len_bytes();
2840 if offset > total_bytes { return None }
2841 if offset == total_bytes {
2842 let line = self.pieces.get(self.root).subtree_newlines;
2846 let line_start_byte = self.try_line_to_byte(line).unwrap_or(0);
2847 let target_char = self.len_chars();
2848 let line_start_char = self.try_byte_to_char(line_start_byte)?;
2849 return Some((line, target_char - line_start_char));
2850 }
2851
2852 let mut current = self.root;
2853 let mut current_line = 0u32;
2854 let mut current_byte = 0u32;
2855 let mut current_char = 0u32;
2856
2857 while current != NIL {
2858 let node = self.pieces.get(current);
2859 let left_node = self.pieces.get(node.left);
2860 let left_bytes = left_node.subtree_len;
2861 let left_newlines = left_node.subtree_newlines;
2862 let left_chars = left_node.subtree_chars;
2863 let p = self.pieces.get_piece(current);
2864 let piece_bytes = p.byte_length;
2865
2866 if offset < current_byte + left_bytes {
2867 current = node.left;
2868
2869 } else if offset < current_byte + left_bytes + piece_bytes {
2870 current_line += left_newlines;
2871 current_char += left_chars;
2872
2873 let rel_byte = offset - (current_byte + left_bytes);
2874
2875 let (local_newlines, col) = if p.newline_count == 0 {
2876 let target_char = self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2877 let rel_char = target_char - p.piece_start_char;
2878 let abs_char = current_char + rel_char;
2879
2880 let line_start_byte = self.try_line_to_byte(current_line)?;
2881 let line_start_char = self.try_byte_to_char(line_start_byte)?;
2882
2883 (0, abs_char - line_start_char)
2884 } else {
2885 let start_index = p.buffer_start_line as usize;
2886 let end_index = start_index + p.newline_count as usize;
2887 let absolute_target = p.byte_offset + rel_byte;
2888
2889 let offsets = &self.buffers.get_newlines(p.buffer)[start_index..end_index];
2890
2891 let local_nl = offsets.partition_point(|&off| off < absolute_target) as u32;
2892
2893 let target_char = self.buffers.byte_to_char_absolute(p.buffer, p.byte_offset + rel_byte);
2894 let col = if local_nl > 0 {
2895 let last_nl_abs_byte = offsets[local_nl as usize - 1];
2896 let last_nl_char = self.buffers.byte_to_char_absolute(p.buffer, last_nl_abs_byte);
2897 target_char - (last_nl_char + 1)
2898 } else {
2899 let line_start_byte = self.try_line_to_byte(current_line)?;
2900 let line_start_char = self.try_byte_to_char(line_start_byte)?;
2901 let rel_char = target_char - p.piece_start_char;
2902 (current_char + rel_char) - line_start_char
2903 };
2904
2905 (local_nl, col)
2906 };
2907
2908 return Some((current_line + local_newlines, col));
2909
2910 } else {
2911 current_line += left_newlines + p.newline_count;
2912 current_byte += left_bytes + piece_bytes;
2913 current_char += left_chars + p.char_count;
2914 current = node.right;
2915 }
2916 }
2917
2918 None
2919 }
2920
2921 #[inline]
2922 #[must_use]
2923 pub fn pieces(&self) -> PieceTreeIter<'_> {
2924 PieceTreeIter::new(&self.pieces, self.root)
2925 }
2926
2927 #[inline]
2928 #[must_use]
2929 pub fn get_line_range(&self, line: u32) -> (u32, u32) {
2930 self.try_get_line_range(line).unwrap()
2931 }
2932
2933 #[inline]
2934 #[must_use]
2935 pub fn try_get_line_range(&self, line: u32) -> Option<(u32, u32)> {
2936 let start = self.try_line_to_byte(line)?;
2937 let end = self.try_line_to_byte(line + 1).unwrap_or_else(|| self.total_length());
2938 Some((start, end))
2939 }
2940
2941 #[inline]
2942 #[must_use]
2943 pub fn get_line_content_allocating(&self, line: u32) -> Option<String> {
2944 let (start, end) = self.try_get_line_range(line)?;
2945
2946 let mut content = String::with_capacity((end - start) as usize);
2947 let mut walker = TreeWalker::new(self);
2948
2949 walker.seek(start);
2950 while walker.offset < end {
2951 if let Some(c) = walker.next() {
2952 content.push(c);
2953 } else {
2954 break;
2955 }
2956 }
2957
2958 Some(content)
2959 }
2960
2961 #[inline]
2963 #[must_use]
2964 pub fn byte(&self, offset: u32) -> u8 {
2965 self.try_byte(offset).unwrap()
2966 }
2967
2968 #[inline]
2970 #[must_use]
2971 pub fn try_byte(&self, offset: u32) -> Option<u8> {
2972 let (node, rel) = self.find_position(offset, false)?;
2973 let p = self.get_piece(node);
2974 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2975 text.as_bytes().get(rel as usize).copied()
2976 }
2977
2978 #[inline]
2981 #[must_use]
2982 pub fn char(&self, char_index: u32) -> char {
2983 self.try_char(char_index).unwrap()
2984 }
2985
2986 #[inline]
2989 #[must_use]
2990 pub fn try_char(&self, char_index: u32) -> Option<char> {
2991 let byte_offset = self.try_char_to_byte(char_index)?;
2992 let (node, rel) = self.find_position(byte_offset, false)?;
2993 let p = self.get_piece(node);
2994 let text = self.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
2995 text[rel as usize..].chars().next()
2996 }
2997
2998 #[inline]
3001 #[must_use]
3002 pub fn slice_chars(&self, char_start: u32, char_end: u32) -> SliceChars<'_> {
3003 let byte_start = self.try_char_to_byte(char_start).unwrap_or(0);
3004 let byte_end = self.try_char_to_byte(char_end).unwrap_or_else(|| self.total_length());
3005 SliceChars {
3006 walker: { let mut w = TreeWalker::new(self); w.seek(byte_start); w },
3007 byte_end,
3008 }
3009 }
3010
3011 #[inline]
3013 #[must_use]
3014 pub fn slice_bytes(&self, byte_start: u32, byte_end: u32) -> SliceChars<'_> {
3015 SliceChars {
3016 walker: { let mut w = TreeWalker::new(self); w.seek(byte_start); w },
3017 byte_end,
3018 }
3019 }
3020
3021 #[inline]
3024 #[must_use]
3025 pub fn line(&self, line: u32) -> TreeSlice<'_> {
3026 self.try_line(line).unwrap()
3027 }
3028
3029 #[inline]
3030 #[must_use]
3031 pub fn try_line(&self, line: u32) -> Option<TreeSlice<'_>> {
3032 let start = self.try_line_to_byte(line)?;
3033 let end = self.try_line_to_byte(line + 1).unwrap_or_else(|| self.len_bytes());
3034
3035 Some(self.slice(start..end))
3036 }
3037
3038 #[inline]
3040 #[must_use]
3041 pub fn len_lines(&self) -> u32 { self.pieces.get(self.root).subtree_newlines + 1 }
3042
3043 #[inline(always)]
3044 #[must_use]
3045 pub fn len_chars(&self) -> u32 { self.pieces.get(self.root).subtree_chars }
3046
3047 #[inline]
3048 #[must_use]
3049 pub fn len_bytes(&self) -> u32 { self.total_length() }
3050
3051 #[inline]
3052 pub fn remove<R>(&mut self, range: R) where R: RangeBounds<u32> {
3053 let start = match range.start_bound() {
3054 Bound::Included(&n) => n,
3055 Bound::Excluded(&n) => n + 1,
3056 Bound::Unbounded => 0,
3057 };
3058 let end = match range.end_bound() {
3059 Bound::Included(&n) => n + 1,
3060 Bound::Excluded(&n) => n,
3061 Bound::Unbounded => self.len_bytes(),
3062 };
3063 if end > start { self.remove_at(start, end - start) }
3064 }
3065
3066 #[inline]
3067 #[must_use]
3068 pub fn char_to_line(&self, char_index: u32) -> u32 {
3069 self.try_char_to_line(char_index).unwrap()
3070 }
3071
3072 #[inline]
3073 #[must_use]
3074 pub fn try_char_to_line(&self, char_index: u32) -> Option<u32> {
3075 let byte_index = self.try_char_to_byte(char_index)?;
3076 self.try_byte_to_line_col(byte_index).map(|(line, _)| line)
3077 }
3078
3079 #[inline]
3080 #[must_use]
3081 pub fn char_to_line_col(&self, char_index: u32) -> (u32, u32) {
3082 self.try_char_to_line_col(char_index).unwrap()
3083 }
3084
3085 #[inline]
3086 #[must_use]
3087 pub fn try_char_to_line_col(&self, char_index: u32) -> Option<(u32, u32)> {
3088 let byte_index = self.try_char_to_byte(char_index)?;
3089 self.try_byte_to_line_col(byte_index)
3090 }
3091
3092 #[inline]
3093 #[must_use]
3094 pub fn line_to_char(&self, line: u32) -> u32 {
3095 self.try_line_to_char(line).unwrap()
3096 }
3097
3098 #[inline]
3099 #[must_use]
3100 pub fn try_line_to_char(&self, line: u32) -> Option<u32> {
3101 let byte_index = self.try_line_to_byte(line)?;
3102 self.try_byte_to_char(byte_index)
3103 }
3104}
3105
3106#[derive(Debug)]
3107pub struct PieceTreeIter<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
3108 arena: &'a Pieces,
3109 stack: SmallVec<[NodeRef; MAX_INLINE_TREE_DEPTH]>,
3110}
3111
3112impl<'a, const MAX_INLINE_TREE_DEPTH: usize> PieceTreeIter<'a, MAX_INLINE_TREE_DEPTH> {
3113 #[inline]
3114 #[must_use]
3115 pub fn new(arena: &'a Pieces, mut root: NodeRef) -> Self {
3116 let mut stack = SmallVec::new();
3117 while root != NIL {
3118 stack.push(root);
3119 root = arena.get(root).left;
3120 }
3121
3122 Self { arena, stack }
3123 }
3124}
3125
3126impl<const MAX_INLINE_TREE_DEPTH: usize> Iterator for PieceTreeIter<'_, MAX_INLINE_TREE_DEPTH> {
3127 type Item = (NodeRef, Piece);
3128
3129 #[inline]
3130 fn next(&mut self) -> Option<Self::Item> {
3131 let node_index = self.stack.pop()?;
3132 let node = self.arena.get(node_index);
3133 let p = self.arena.get_piece(node_index);
3134
3135 let mut current = node.right;
3136 while current != NIL {
3137 self.stack.push(current);
3138 current = self.arena.get(current).left;
3139 }
3140
3141 Some((node_index, p))
3142 }
3143}
3144
3145#[derive(Clone, Copy, PartialEq, Debug)]
3146enum Direction { Left, Center, Right }
3147
3148#[derive(Debug)]
3149pub struct TreeWalker<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
3150 tree: &'a PieceTree,
3151 stack: SmallVec<[(NodeRef, Direction); MAX_INLINE_TREE_DEPTH]>,
3152 current_str: str::Chars<'a>,
3153 pub offset: u32,
3154}
3155
3156impl<'a, const MAX_INLINE_TREE_DEPTH: usize> TreeWalker<'a, MAX_INLINE_TREE_DEPTH> {
3157 #[inline]
3158 #[must_use]
3159 pub fn new(tree: &'a PieceTree) -> Self {
3160 let mut walker = Self {
3161 tree,
3162 stack: SmallVec::new(),
3163 current_str: "".chars(),
3164 offset: 0,
3165 };
3166 if tree.root != NIL {
3167 walker.stack.push((tree.root, Direction::Left));
3168 }
3169 walker.populate_chars();
3170 walker
3171 }
3172
3173 #[inline]
3174 pub fn seek(&mut self, target: u32) {
3175 self.stack.clear();
3176 self.offset = target;
3177 self.current_str = "".chars();
3178
3179 if self.tree.root == NIL { return; }
3180
3181 let mut current = self.tree.root;
3182 let mut current_offset = target;
3183
3184 while current != NIL {
3185 let node = self.tree.pieces.get(current);
3186 let p = self.tree.pieces.get_piece(current);
3187 let left_len = self.tree.pieces.get(node.left).subtree_len;
3188 let piece_len = p.byte_length;
3189
3190 if current_offset < left_len {
3191 self.stack.push((current, Direction::Center));
3192 current = node.left;
3193 } else if current_offset < left_len + piece_len {
3194 self.stack.push((current, Direction::Right));
3195 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
3196 let rel_offset = current_offset - left_len;
3197 self.current_str = text[rel_offset as usize..].chars();
3198 break;
3199 } else {
3200 current_offset -= left_len + piece_len;
3201 current = node.right;
3202 }
3203 }
3204 }
3205
3206 #[inline]
3207 fn populate_chars(&mut self) {
3208 while let Some((node_index, dir)) = self.stack.pop() {
3209 let node = self.tree.pieces.get(node_index);
3210 match dir {
3211 Direction::Left => {
3212 self.stack.push((node_index, Direction::Center));
3213 if node.left != NIL { self.stack.push((node.left, Direction::Left)); }
3214 }
3215
3216 Direction::Center => {
3217 self.stack.push((node_index, Direction::Right));
3218 let p = self.tree.pieces.get_piece(node_index);
3219 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
3220 self.current_str = text.chars();
3221 return;
3222 }
3223
3224 Direction::Right => {
3225 if node.right != NIL { self.stack.push((node.right, Direction::Left)); }
3226 }
3227 }
3228 }
3229 }
3230}
3231
3232impl Iterator for TreeWalker<'_> {
3233 type Item = char;
3234
3235 #[inline(always)]
3236 fn next(&mut self) -> Option<char> {
3237 loop {
3238 if let Some(c) = self.current_str.next() {
3239 self.offset += c.len_utf8() as u32;
3240 return Some(c);
3241 }
3242
3243 if self.stack.is_empty() { return None; }
3244 self.populate_chars();
3245 }
3246 }
3247}
3248
3249#[derive(Debug)]
3250pub struct ReverseTreeWalker<'a, const MAX_INLINE_TREE_DEPTH: usize = 32> {
3251 tree: &'a PieceTree,
3252 stack: SmallVec<[(NodeRef, bool); MAX_INLINE_TREE_DEPTH]>,
3253 current_str: str::Chars<'a>,
3254}
3255
3256impl<'a, const MAX_INLINE_TREE_DEPTH: usize> ReverseTreeWalker<'a, MAX_INLINE_TREE_DEPTH> {
3257 #[inline(always)]
3258 #[must_use]
3259 pub fn new(tree: &'a PieceTree) -> Self {
3260 let mut walker = Self {
3261 tree,
3262 stack: SmallVec::new(),
3263 current_str: "".chars(),
3264 };
3265 walker.push_rightmost(tree.root);
3266 walker
3267 }
3268
3269 #[inline]
3270 #[must_use]
3271 pub fn new_at(tree: &'a PieceTree, target_offset: u32) -> Self {
3272 let mut walker = Self {
3273 tree,
3274 stack: SmallVec::new(),
3275 current_str: "".chars(),
3276 };
3277 walker.seek(target_offset);
3278 walker
3279 }
3280
3281 #[inline(always)]
3282 fn push_rightmost(&mut self, mut node: NodeRef) {
3283 while node != NIL {
3284 self.stack.push((node, false));
3285 node = self.tree.pieces.get(node).right;
3286 }
3287 }
3288
3289 #[inline]
3290 pub fn seek(&mut self, mut target_offset: u32) {
3291 self.stack.clear();
3292 self.current_str = "".chars();
3293
3294 if self.tree.root == NIL { return; }
3295
3296 let total_bytes = self.tree.len_bytes();
3297
3298 if target_offset > total_bytes {
3299 target_offset = total_bytes;
3300 }
3301 if target_offset == total_bytes {
3302 self.push_rightmost(self.tree.root);
3303 return;
3304 }
3305
3306 let mut current = self.tree.root;
3307 let mut current_offset = target_offset;
3308
3309 while current != NIL {
3310 let node = self.tree.pieces.get(current);
3311 let p = self.tree.pieces.get_piece(current);
3312 let left_len = self.tree.pieces.get(node.left).subtree_len;
3313 let piece_len = p.byte_length;
3314
3315 if current_offset < left_len {
3316 self.stack.push((current, true));
3317 current = node.left;
3318
3319 } else if current_offset < left_len + piece_len {
3320 self.stack.push((current, true));
3321
3322 let text = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
3323 let rel_offset = current_offset - left_len;
3324
3325 self.current_str = text[..rel_offset as usize].chars();
3327
3328 break;
3329
3330 } else {
3331 self.stack.push((current, false));
3332 current_offset -= left_len + piece_len;
3333 current = node.right;
3334 }
3335 }
3336 }
3337}
3338
3339impl Iterator for ReverseTreeWalker<'_> {
3340 type Item = char;
3341
3342 #[inline]
3343 fn next(&mut self) -> Option<Self::Item> {
3344 if let Some(c) = self.current_str.next_back() { return Some(c); }
3345
3346 while let Some((node_index, visited_right)) = self.stack.pop() {
3347 let node = self.tree.pieces.get(node_index);
3348 if visited_right {
3349 self.push_rightmost(node.left);
3350 } else {
3351 self.stack.push((node_index, true));
3352
3353 let p = self.tree.pieces.get_piece(node_index);
3354 let text_slice = self.tree.buffers.get_slice(p.buffer, p.byte_offset, p.byte_length);
3355
3356 self.current_str = text_slice.chars();
3357
3358 if let Some(c) = self.current_str.next_back() { return Some(c); }
3359 }
3360 }
3361
3362 None
3363 }
3364}
3365
3366impl PieceTree {
3367 #[inline]
3368 pub fn debug(&self, f: &mut impl core::fmt::Write) -> core::fmt::Result {
3369 writeln!(f, "\n--- Tree State (Root: {:?}) ---", self.root)?;
3370 self.print_inorder(f, self.root, &mut None, 0)?;
3371 writeln!(f, "------------------------------\n")
3372 }
3373
3374 fn print_inorder(&self, f: &mut impl core::fmt::Write, node: NodeRef, last: &mut Option<Piece>, depth: usize) -> core::fmt::Result {
3375 if node == NIL { return Ok(()) }
3376
3377 let n = self.pieces.nodes[node];
3378
3379 self.print_inorder(f, n.left, last, depth + 1)?;
3380
3381 let cur = self.get_piece(node);
3382
3383 let warning = if let Some(prev) = last {
3387 if prev.buffer == cur.buffer
3388 && prev.byte_offset + prev.byte_length == cur.byte_offset
3389 {
3390 " --------- [!!! MERGEABLE NEIGHBORS NOT MERGED !!!] ---------"
3391 } else {
3392 ""
3393 }
3394 } else {
3395 ""
3396 };
3397
3398 let Piece { buffer, byte_offset: offset, byte_length: length, .. } = cur;
3399
3400 writeln!(
3401 f,
3402 "{:indent$}Node {node:?}: Buf={}, Off={offset}, Len={length}{warning}",
3403 "", buffer.as_u32(), indent = depth * 4
3404 )?;
3405
3406 *last = Some(cur);
3407
3408 self.print_inorder(f, n.right, last, depth + 1)
3409 }
3410}
3411
3412pub fn assert_state(tree: &PieceTree, expected: &str) {
3413 let tree_text = tree.to_string();
3414
3415 assert_eq!(tree_text, expected, "Text mismatch");
3416
3417 if !expected.is_empty() {
3418 let offsets = [0, expected.len() / 2, expected.len() - 1];
3419 for off in offsets {
3420 let chunk = tree.read_largest_contigous_chunk_at_byte(off as u32).0;
3421 let chunk_str = str::from_utf8(chunk).unwrap();
3422 assert!(
3423 expected[off..].starts_with(chunk_str),
3424 "Chunk mismatch at offset {}",
3425 off
3426 );
3427 }
3428 }
3429}
3430
3431pub fn assert_invariants(tree: &PieceTree) {
3432 fn check(tree: &PieceTree, node: NodeRef) -> (usize, usize) {
3433 if node == NIL { return (0, 1) }
3434
3435 let n = tree.pieces.nodes[node];
3436 let piece = tree.get_piece(node);
3437
3438 let (l_len, l_bh) = check(tree, n.left);
3439 let (r_len, r_bh) = check(tree, n.right);
3440
3441 let expected_len = l_len + piece.byte_length as usize + r_len;
3442 assert_eq!(n.subtree_len as usize, expected_len, "subtree_len mismatch");
3443
3444 if n.color() == Color::Red {
3445 assert_eq!(
3446 tree.pieces.nodes[n.left].color(),
3447 Color::Black,
3448 "red node with red left child"
3449 );
3450 assert_eq!(
3451 tree.pieces.nodes[n.right].color(),
3452 Color::Black,
3453 "red node with red right child"
3454 );
3455 }
3456
3457 assert_eq!(l_bh, r_bh, "black height mismatch");
3458
3459 let bh = l_bh + usize::from(n.color() == Color::Black);
3460 (expected_len, bh)
3461 }
3462
3463 if tree.root == NIL {
3464 assert_eq!(tree.total_length(), 0, "Empty tree has nonzero length");
3465 } else {
3466 assert_eq!(
3467 tree.pieces.nodes[tree.root].color(),
3468 Color::Black,
3469 "root is not black"
3470 );
3471 let (len, _) = check(tree, tree.root);
3472 assert_eq!(len, tree.total_length() as usize, "Tree length and root length differ");
3473
3474 }
3475}
3476
3477pub fn assert_piece_metadata(tree: &PieceTree) {
3478 fn collect(tree: &PieceTree, node: NodeRef, out: &mut Vec<Piece>) {
3479 if node == NIL { return }
3480
3481 let n = tree.pieces.nodes[node];
3482
3483 collect(tree, n.left, out);
3484 out.push(tree.pieces.get_piece(node));
3485 collect(tree, n.right, out);
3486 }
3487
3488 let mut pieces = Vec::new();
3489 collect(tree, tree.root, &mut pieces);
3490
3491 for p in &pieces {
3492 let buf = tree.buffers.get(p.buffer);
3493 let start = p.byte_offset as usize;
3494 let end = start + p.byte_length as usize;
3495
3496 assert!(end <= buf.len(), "Piece points past end of buffer");
3497 assert!(p.byte_length > 0, "Zero-length piece found");
3498
3499 let slice = &buf[start..end];
3500 let (actual_chars, actual_nl) = count_chars_and_newlines(slice.as_bytes());
3501 assert_eq!(p.char_count, actual_chars, "char_count mismatch");
3502 assert_eq!(p.newline_count, actual_nl, "newline_count mismatch");
3503
3504 let prefix = &buf.as_bytes()[..p.byte_offset as usize];
3508 let actual_start_char = bytecount::num_chars(prefix) as u32;
3509 let actual_start_line = bytecount::count(prefix, b'\n') as u32;
3510
3511 assert_eq!(p.piece_start_char, actual_start_char,
3512 "piece_start_char mismatch buffer={} offset={}", p.buffer.as_u32(), p.byte_offset);
3513
3514 assert_eq!(p.buffer_start_line, actual_start_line,
3515 "buffer_start_line mismatch buffer={} offset={}", p.buffer.as_u32(), p.byte_offset);
3516
3517 let nl_offsets = &tree.buffers.get_newlines(p.buffer)
3521 [p.buffer_start_line as usize..(p.buffer_start_line + p.newline_count) as usize];
3522
3523 for (i, &abs_byte) in nl_offsets.iter().enumerate() {
3524 assert!(
3525 abs_byte >= p.byte_offset && abs_byte < p.byte_offset + p.byte_length,
3526 "newline_offsets[{}] outside piece", p.buffer_start_line as usize + i
3527 );
3528
3529 assert_eq!(
3530 buf.as_bytes()[abs_byte as usize], b'\n',
3531 "newline_offsets[{}] not a newline", p.buffer_start_line as usize + i
3532 );
3533 }
3534 }
3535}
3536
3537pub fn assert_no_mergeable_neighbors(tree: &PieceTree) {
3538 fn inorder(tree: &PieceTree, node: NodeRef, last: &mut Option<Piece>) {
3539 if node == NIL { return }
3540
3541 let n = tree.pieces.nodes[node];
3542 inorder(tree, n.left, last);
3543
3544 let cur = tree.get_piece(node);
3545
3546 if let Some(prev) = *last {
3547 if prev.buffer == cur.buffer
3548 && prev.byte_offset + prev.byte_length == cur.byte_offset
3549 {
3550 panic!("Mergeable neighboring pieces were left unmerged");
3551 }
3552 }
3553
3554 *last = Some(cur);
3555 inorder(tree, n.right, last);
3556 }
3557
3558 let mut last = None;
3559 inorder(tree, tree.root, &mut last);
3560}
3561
3562pub fn assert_coordinates(tree: &PieceTree, oracle: &str) {
3563 #[inline]
3564 fn oracle_offset_to_line_col(s: &str, byte_offset: usize) -> (usize, usize) {
3565 let slice = &s[..byte_offset];
3566 let line = bytecount::count(slice.as_bytes(), b'\n');
3567 let last_nl = slice.rfind('\n').map_or(0, |i| i + 1);
3568 let col = bytecount::num_chars(s[last_nl..byte_offset].as_bytes());
3569 (line, col)
3570 }
3571
3572 #[inline]
3573 fn oracle_line_to_offset(s: &str, target_line: usize) -> usize {
3574 if target_line == 0 { return 0 }
3575
3576 let mut line = 0;
3577 for (i, c) in s.char_indices() {
3578 if c == '\n' {
3579 line += 1;
3580 if line == target_line { return i + 1; }
3581 }
3582 }
3583
3584 s.len()
3585 }
3586
3587 fn check_coordinate(tree: &PieceTree, oracle: &str, byte_index: u32) {
3588 let char_index = bytecount::num_chars(oracle[..byte_index as usize].as_bytes()) as u32;
3589
3590 assert_eq!(tree.char_to_byte(char_index), byte_index,
3591 "char_to_byte({}) wrong", char_index);
3592
3593 assert_eq!(tree.byte_to_char(byte_index), char_index,
3594 "byte_to_char({}) wrong", byte_index);
3595
3596 let expected_lc = oracle_offset_to_line_col(oracle, byte_index as usize);
3597 assert_eq!(
3598 tree.byte_to_line_col(byte_index),
3599 (expected_lc.0 as u32, expected_lc.1 as u32),
3600 "offset_to_line_col({}) wrong", byte_index
3601 );
3602 }
3603
3604 let total_bytes = oracle.len() as u32;
3605 let total_chars = oracle.chars().count() as u32;
3606
3607 check_coordinate(tree, oracle, 0);
3611 if total_bytes > 0 {
3612 check_coordinate(tree, oracle, total_bytes - 1);
3613 check_coordinate(tree, oracle, total_bytes / 2);
3614 }
3615
3616
3617 for i in 0u32..8 {
3621 let byte =
3622 ((total_bytes as u64 * ((i as u64 * 2_654_435_761) & 0xFFFF_FFFF)) >> 32) as u32 % total_bytes.max(1);
3623
3624 let byte = oracle.as_bytes()[..byte as usize]
3626 .iter().rposition(|&b| !(0x80..0xC0).contains(&b))
3627 .map_or(0, |i| i as u32);
3628
3629 check_coordinate(tree, oracle, byte);
3630 }
3631
3632 assert_eq!(tree.char_to_byte(total_chars), total_bytes);
3636 assert_eq!(tree.byte_to_char(total_bytes), total_chars);
3637 assert_eq!(tree.try_char_to_byte(total_chars + 1), None);
3638 assert_eq!(tree.try_byte_to_char(total_bytes + 1), None);
3639 assert_eq!(tree.try_byte_to_line_col(total_bytes + 1), None);
3640
3641 let total_lines = oracle.chars().filter(|&c| c == '\n').count() + 1;
3645 for line in [0, total_lines / 2, total_lines.saturating_sub(1)] {
3646 let expected = oracle_line_to_offset(oracle, line) as u32;
3647 assert_eq!(tree.try_line_to_byte(line as u32), Some(expected),
3648 "line_to_offset({}) wrong", line);
3649 }
3650
3651 assert_eq!(tree.try_line_to_byte(total_lines as u32), None);
3652}