ropey/tree/
node_children.rs

1use std::fmt;
2use std::iter::{Iterator, Zip};
3use std::slice;
4use std::sync::Arc;
5
6use crate::crlf;
7use crate::tree::{self, Node, TextInfo, MAX_BYTES};
8
9const MAX_LEN: usize = tree::MAX_CHILDREN;
10
11/// A fixed-capacity vec of child Arc-pointers and child metadata.
12///
13/// The unsafe guts of this are implemented in NodeChildrenInternal
14/// lower down in this file.
15#[derive(Clone)]
16#[repr(C)]
17pub(crate) struct NodeChildren(inner::NodeChildrenInternal);
18
19impl NodeChildren {
20    /// Creates a new empty array.
21    pub fn new() -> Self {
22        NodeChildren(inner::NodeChildrenInternal::new())
23    }
24
25    /// Current length of the array.
26    pub fn len(&self) -> usize {
27        self.0.len() as usize
28    }
29
30    /// Returns whether the array is full or not.
31    pub fn is_full(&self) -> bool {
32        self.len() == MAX_LEN
33    }
34
35    /// Access to the nodes array.
36    pub fn nodes(&self) -> &[Arc<Node>] {
37        self.0.nodes()
38    }
39
40    /// Mutable access to the nodes array.
41    pub fn nodes_mut(&mut self) -> &mut [Arc<Node>] {
42        self.0.nodes_mut()
43    }
44
45    /// Access to the info array.
46    pub fn info(&self) -> &[TextInfo] {
47        self.0.info()
48    }
49
50    /// Mutable access to the info array.
51    pub fn info_mut(&mut self) -> &mut [TextInfo] {
52        self.0.info_mut()
53    }
54
55    /// Mutable access to both the info and nodes arrays simultaneously.
56    pub fn data_mut(&mut self) -> (&mut [TextInfo], &mut [Arc<Node>]) {
57        self.0.data_mut()
58    }
59
60    /// Updates the text info of the child at `idx`.
61    pub fn update_child_info(&mut self, idx: usize) {
62        let (info, nodes) = self.0.data_mut();
63        info[idx] = nodes[idx].text_info();
64    }
65
66    /// Pushes an item into the end of the array.
67    ///
68    /// Increases length by one.  Panics if already full.
69    pub fn push(&mut self, item: (TextInfo, Arc<Node>)) {
70        self.0.push(item)
71    }
72
73    /// Pushes an element onto the end of the array, and then splits it in half,
74    /// returning the right half.
75    ///
76    /// This works even when the array is full.
77    pub fn push_split(&mut self, new_child: (TextInfo, Arc<Node>)) -> Self {
78        let r_count = (self.len() + 1) / 2;
79        let l_count = (self.len() + 1) - r_count;
80
81        let mut right = self.split_off(l_count);
82        right.push(new_child);
83        right
84    }
85
86    /// Attempts to merge two nodes, and if it's too much data to merge
87    /// equi-distributes it between the two.
88    ///
89    /// Returns:
90    ///
91    /// - True: merge was successful.
92    /// - False: merge failed, equidistributed instead.
93    pub fn merge_distribute(&mut self, idx1: usize, idx2: usize) -> bool {
94        assert!(idx1 < idx2);
95        assert!(idx2 < self.len());
96        let remove_right = {
97            let ((_, node1), (_, node2)) = self.get_two_mut(idx1, idx2);
98            let node1 = Arc::make_mut(node1);
99            let node2 = Arc::make_mut(node2);
100            match *node1 {
101                Node::Leaf(ref mut text1) => {
102                    if let Node::Leaf(ref mut text2) = *node2 {
103                        if (text1.len() + text2.len()) <= tree::MAX_BYTES {
104                            text1.push_str(text2);
105                            true
106                        } else {
107                            let right = text1.push_str_split(text2);
108                            *text2 = right;
109                            false
110                        }
111                    } else {
112                        panic!("Siblings have different node types");
113                    }
114                }
115
116                Node::Internal(ref mut children1) => {
117                    if let Node::Internal(ref mut children2) = *node2 {
118                        if (children1.len() + children2.len()) <= MAX_LEN {
119                            for _ in 0..children2.len() {
120                                children1.push(children2.remove(0));
121                            }
122                            true
123                        } else {
124                            children1.distribute_with(children2);
125                            false
126                        }
127                    } else {
128                        panic!("Siblings have different node types");
129                    }
130                }
131            }
132        };
133
134        if remove_right {
135            self.remove(idx2);
136            self.update_child_info(idx1);
137            return true;
138        } else {
139            self.update_child_info(idx1);
140            self.update_child_info(idx2);
141            return false;
142        }
143    }
144
145    /// Equi-distributes the children between the two child arrays,
146    /// preserving ordering.
147    pub fn distribute_with(&mut self, other: &mut Self) {
148        let r_target_len = (self.len() + other.len()) / 2;
149        while other.len() < r_target_len {
150            other.insert(0, self.pop());
151        }
152        while other.len() > r_target_len {
153            self.push(other.remove(0));
154        }
155    }
156
157    /// If the children are leaf nodes, compacts them to take up the fewest
158    /// nodes.
159    pub fn compact_leaves(&mut self) {
160        if !self.nodes()[0].is_leaf() || self.len() < 2 {
161            return;
162        }
163
164        let mut i = 1;
165        while i < self.len() {
166            if (self.nodes()[i - 1].leaf_text().len() + self.nodes()[i].leaf_text().len())
167                <= MAX_BYTES
168            {
169                // Scope to contain borrows
170                {
171                    let ((_, node_l), (_, node_r)) = self.get_two_mut(i - 1, i);
172                    let text_l = Arc::make_mut(node_l).leaf_text_mut();
173                    let text_r = node_r.leaf_text();
174                    text_l.push_str(text_r);
175                }
176                self.remove(i);
177            } else if self.nodes()[i - 1].leaf_text().len() < MAX_BYTES {
178                // Scope to contain borrows
179                {
180                    let ((_, node_l), (_, node_r)) = self.get_two_mut(i - 1, i);
181                    let text_l = Arc::make_mut(node_l).leaf_text_mut();
182                    let text_r = Arc::make_mut(node_r).leaf_text_mut();
183                    let split_idx_r = crlf::prev_break(MAX_BYTES - text_l.len(), text_r.as_bytes());
184                    text_l.push_str(&text_r[..split_idx_r]);
185                    text_r.truncate_front(split_idx_r);
186                }
187                i += 1;
188            } else {
189                i += 1;
190            }
191        }
192
193        for i in 0..self.len() {
194            self.update_child_info(i);
195        }
196    }
197
198    /// Pops an item off the end of the array and returns it.
199    ///
200    /// Decreases length by one.  Panics if already empty.
201    pub fn pop(&mut self) -> (TextInfo, Arc<Node>) {
202        self.0.pop()
203    }
204
205    /// Inserts an item into the the array at the given index.
206    ///
207    /// Increases length by one.  Panics if already full.  Preserves ordering
208    /// of the other items.
209    pub fn insert(&mut self, idx: usize, item: (TextInfo, Arc<Node>)) {
210        self.0.insert(idx, item)
211    }
212
213    /// Inserts an element into a the array, and then splits it in half, returning
214    /// the right half.
215    ///
216    /// This works even when the array is full.
217    pub fn insert_split(&mut self, idx: usize, item: (TextInfo, Arc<Node>)) -> Self {
218        assert!(self.len() > 0);
219        assert!(idx <= self.len());
220        let extra = if idx < self.len() {
221            let extra = self.pop();
222            self.insert(idx, item);
223            extra
224        } else {
225            item
226        };
227
228        self.push_split(extra)
229    }
230
231    /// Removes the item at the given index from the the array.
232    ///
233    /// Decreases length by one.  Preserves ordering of the other items.
234    pub fn remove(&mut self, idx: usize) -> (TextInfo, Arc<Node>) {
235        self.0.remove(idx)
236    }
237
238    /// Splits the array in two at `idx`, returning the right part of the split.
239    ///
240    /// TODO: implement this more efficiently.
241    pub fn split_off(&mut self, idx: usize) -> Self {
242        assert!(idx <= self.len());
243
244        let mut other = NodeChildren::new();
245        let count = self.len() - idx;
246        for _ in 0..count {
247            other.push(self.remove(idx));
248        }
249
250        other
251    }
252
253    /// Fetches two children simultaneously, returning mutable references
254    /// to their info and nodes.
255    ///
256    /// `idx1` must be less than `idx2`.
257    pub fn get_two_mut(
258        &mut self,
259        idx1: usize,
260        idx2: usize,
261    ) -> (
262        (&mut TextInfo, &mut Arc<Node>),
263        (&mut TextInfo, &mut Arc<Node>),
264    ) {
265        assert!(idx1 < idx2);
266        assert!(idx2 < self.len());
267
268        let split_idx = idx1 + 1;
269        let (info, nodes) = self.data_mut();
270        let (info1, info2) = info.split_at_mut(split_idx);
271        let (nodes1, nodes2) = nodes.split_at_mut(split_idx);
272
273        (
274            (&mut info1[idx1], &mut nodes1[idx1]),
275            (&mut info2[idx2 - split_idx], &mut nodes2[idx2 - split_idx]),
276        )
277    }
278
279    /// Creates an iterator over the array's items.
280    pub fn iter(&self) -> Zip<slice::Iter<TextInfo>, slice::Iter<Arc<Node>>> {
281        Iterator::zip(self.info().iter(), self.nodes().iter())
282    }
283
284    #[allow(clippy::needless_range_loop)]
285    pub fn combined_info(&self) -> TextInfo {
286        let info = self.info();
287        let mut acc = TextInfo::new();
288
289        // Doing this with an explicit loop is notably faster than
290        // using an iterator in this case.
291        for i in 0..info.len() {
292            acc += info[i];
293        }
294
295        acc
296    }
297
298    /// Returns the child index and left-side-accumulated text info of the
299    /// first child that matches the given predicate.
300    ///
301    /// If no child matches the predicate, the last child is returned.
302    #[inline(always)]
303    pub fn search_by<F>(&self, pred: F) -> (usize, TextInfo)
304    where
305        // (left-accumulated start info, left-accumulated end info)
306        F: Fn(TextInfo, TextInfo) -> bool,
307    {
308        debug_assert!(self.len() > 0);
309
310        let mut accum = TextInfo::new();
311        let mut idx = 0;
312        for info in self.info()[0..(self.len() - 1)].iter() {
313            let next_accum = accum + *info;
314            if pred(accum, next_accum) {
315                break;
316            }
317            accum = next_accum;
318            idx += 1;
319        }
320
321        (idx, accum)
322    }
323
324    /// Returns the child index and left-side-accumulated text info of the
325    /// child that contains the given byte.
326    ///
327    /// One-past-the end is valid, and will return the last child.
328    pub fn search_byte_idx(&self, byte_idx: usize) -> (usize, TextInfo) {
329        let (idx, accum) = self.search_by(|_, end| byte_idx < end.bytes as usize);
330
331        debug_assert!(
332            byte_idx <= (accum.bytes + self.info()[idx].bytes) as usize,
333            "Index out of bounds."
334        );
335
336        (idx, accum)
337    }
338
339    /// Returns the child index and left-side-accumulated text info of the
340    /// child that contains the given char.
341    ///
342    /// One-past-the end is valid, and will return the last child.
343    pub fn search_char_idx(&self, char_idx: usize) -> (usize, TextInfo) {
344        let (idx, accum) = self.search_by(|_, end| char_idx < end.chars as usize);
345
346        debug_assert!(
347            char_idx <= (accum.chars + self.info()[idx].chars) as usize,
348            "Index out of bounds."
349        );
350
351        (idx, accum)
352    }
353
354    /// Returns the child index and left-side-accumulated text info of the
355    /// child that contains the given utf16 code unit offset.
356    ///
357    /// One-past-the end is valid, and will return the last child.
358    pub fn search_utf16_code_unit_idx(&self, utf16_idx: usize) -> (usize, TextInfo) {
359        let (idx, accum) =
360            self.search_by(|_, end| utf16_idx < (end.chars + end.utf16_surrogates) as usize);
361
362        debug_assert!(
363            utf16_idx
364                <= (accum.chars
365                    + accum.utf16_surrogates
366                    + self.info()[idx].chars
367                    + self.info()[idx].utf16_surrogates) as usize,
368            "Index out of bounds."
369        );
370
371        (idx, accum)
372    }
373
374    /// Same as `search_char_idx()` above, except that it only calulates the
375    /// left-side-accumulated _char_ index rather than the full text info.
376    ///
377    /// Return is (child_index, left_acc_char_index)
378    ///
379    /// One-past-the end is valid, and will return the last child.
380    #[inline(always)]
381    pub fn search_char_idx_only(&self, char_idx: usize) -> (usize, usize) {
382        debug_assert!(self.len() > 0);
383
384        let mut accum_char_idx = 0;
385        let mut idx = 0;
386        for info in self.info()[0..(self.len() - 1)].iter() {
387            let next_accum = accum_char_idx + info.chars as usize;
388            if char_idx < next_accum {
389                break;
390            }
391            accum_char_idx = next_accum;
392            idx += 1;
393        }
394
395        debug_assert!(
396            char_idx <= (accum_char_idx + self.info()[idx].chars as usize) as usize,
397            "Index out of bounds."
398        );
399
400        (idx, accum_char_idx)
401    }
402
403    /// Returns the child index and left-side-accumulated text info of the
404    /// child that contains the given line break.
405    ///
406    /// Beginning of the rope is considered index 0, although is not
407    /// considered a line break for the returned left-side-accumulated
408    /// text info.
409    ///
410    /// One-past-the end is valid, and will return the last child.
411    pub fn search_line_break_idx(&self, line_break_idx: usize) -> (usize, TextInfo) {
412        let (idx, accum) = self.search_by(|_, end| line_break_idx <= end.line_breaks as usize);
413
414        debug_assert!(
415            line_break_idx <= (accum.line_breaks + self.info()[idx].line_breaks + 1) as usize,
416            "Index out of bounds."
417        );
418
419        (idx, accum)
420    }
421
422    /// Returns the child indices at the start and end of the given char
423    /// range, and returns their left-side-accumulated char indices as well.
424    ///
425    /// Return is:
426    /// (
427    ///     (left_node_index, left_acc_left_side_char_index),
428    ///     (right_node_index, right_acc_left_side_char_index),
429    /// )
430    ///
431    /// One-past-the end is valid, and corresponds to the last child.
432    #[inline(always)]
433    pub fn search_char_idx_range(
434        &self,
435        start_idx: usize,
436        end_idx: usize,
437    ) -> ((usize, usize), (usize, usize)) {
438        debug_assert!(start_idx <= end_idx);
439        debug_assert!(self.len() > 0);
440
441        let mut accum_char_idx = 0;
442        let mut idx = 0;
443
444        // Find left child and info
445        for info in self.info()[..(self.len() - 1)].iter() {
446            let next_accum = accum_char_idx + info.chars as usize;
447            if start_idx < next_accum {
448                break;
449            }
450            accum_char_idx = next_accum;
451            idx += 1;
452        }
453        let l_child_i = idx;
454        let l_acc_info = accum_char_idx;
455
456        // Find right child and info
457        for info in self.info()[idx..(self.len() - 1)].iter() {
458            let next_accum = accum_char_idx + info.chars as usize;
459            if end_idx <= next_accum {
460                break;
461            }
462            accum_char_idx = next_accum;
463            idx += 1;
464        }
465
466        #[cfg(any(test, debug_assertions))]
467        assert!(
468            end_idx <= accum_char_idx + self.info()[idx].chars as usize,
469            "Index out of bounds."
470        );
471
472        ((l_child_i, l_acc_info), (idx, accum_char_idx))
473    }
474
475    // Debug function, to help verify tree integrity
476    pub fn is_info_accurate(&self) -> bool {
477        for (info, node) in self.info().iter().zip(self.nodes().iter()) {
478            if *info != node.text_info() {
479                return false;
480            }
481        }
482        true
483    }
484}
485
486impl fmt::Debug for NodeChildren {
487    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
488        f.debug_struct("NodeChildren")
489            .field("len", &self.len())
490            .field("info", &&self.info())
491            .field("nodes", &&self.nodes())
492            .finish()
493    }
494}
495
496//===========================================================================
497
498/// The unsafe guts of NodeChildren, exposed through a safe API.
499///
500/// Try to keep this as small as possible, and implement functionality on
501/// NodeChildren via the safe APIs whenever possible.
502///
503/// It's split out this way because it was too easy to accidentally access the
504/// fixed size arrays directly, leading to memory-unsafety bugs when accidentally
505/// accessing elements that are semantically out of bounds.  This happened once,
506/// and it was a pain to track down--as memory safety bugs often are.
507mod inner {
508    use super::{Node, TextInfo, MAX_LEN};
509    use std::mem;
510    use std::mem::MaybeUninit;
511    use std::ptr;
512    use std::sync::Arc;
513
514    /// This is essentially a fixed-capacity, stack-allocated `Vec`.  However,
515    /// it actually containts _two_ arrays rather than just one, but which
516    /// share a length.
517    #[repr(C)]
518    pub(crate) struct NodeChildrenInternal {
519        /// An array of the child nodes.
520        /// INVARIANT: The nodes from 0..len must be initialized
521        nodes: [MaybeUninit<Arc<Node>>; MAX_LEN],
522        /// An array of the child node text infos
523        /// INVARIANT: The nodes from 0..len must be initialized
524        info: [MaybeUninit<TextInfo>; MAX_LEN],
525        len: u8,
526    }
527
528    impl NodeChildrenInternal {
529        /// Creates a new empty array.
530        #[inline(always)]
531        pub fn new() -> NodeChildrenInternal {
532            // SAFETY: Uninit data is valid for arrays of MaybeUninit.
533            // len is zero, so it's ok for all of them to be uninit
534            NodeChildrenInternal {
535                nodes: unsafe { MaybeUninit::uninit().assume_init() },
536                info: unsafe { MaybeUninit::uninit().assume_init() },
537                len: 0,
538            }
539        }
540
541        /// Current length of the array.
542        #[inline(always)]
543        pub fn len(&self) -> usize {
544            self.len as usize
545        }
546
547        /// Access to the nodes array.
548        #[inline(always)]
549        pub fn nodes(&self) -> &[Arc<Node>] {
550            // SAFETY: MaybeUninit<T> is layout compatible with T, and
551            // the nodes from 0..len are guaranteed to be initialized
552            unsafe { mem::transmute(&self.nodes[..(self.len())]) }
553        }
554
555        /// Mutable access to the nodes array.
556        #[inline(always)]
557        pub fn nodes_mut(&mut self) -> &mut [Arc<Node>] {
558            // SAFETY: MaybeUninit<T> is layout compatible with T, and
559            // the nodes from 0..len are guaranteed to be initialized
560            unsafe { mem::transmute(&mut self.nodes[..(self.len as usize)]) }
561        }
562
563        /// Access to the info array.
564        #[inline(always)]
565        pub fn info(&self) -> &[TextInfo] {
566            // SAFETY: MaybeUninit<T> is layout compatible with T, and
567            // the info from 0..len are guaranteed to be initialized
568            unsafe { mem::transmute(&self.info[..(self.len())]) }
569        }
570
571        /// Mutable access to the info array.
572        #[inline(always)]
573        pub fn info_mut(&mut self) -> &mut [TextInfo] {
574            // SAFETY: MaybeUninit<T> is layout compatible with T, and
575            // the info from 0..len are guaranteed to be initialized
576            unsafe { mem::transmute(&mut self.info[..(self.len as usize)]) }
577        }
578
579        /// Mutable access to both the info and nodes arrays simultaneously.
580        #[inline(always)]
581        pub fn data_mut(&mut self) -> (&mut [TextInfo], &mut [Arc<Node>]) {
582            // SAFETY: MaybeUninit<T> is layout compatible with T, and
583            // the info from 0..len are guaranteed to be initialized
584            (
585                unsafe { mem::transmute(&mut self.info[..(self.len as usize)]) },
586                unsafe { mem::transmute(&mut self.nodes[..(self.len as usize)]) },
587            )
588        }
589
590        /// Pushes an item into the end of the array.
591        ///
592        /// Increases length by one.  Panics if already full.
593        #[inline(always)]
594        pub fn push(&mut self, item: (TextInfo, Arc<Node>)) {
595            assert!(self.len() < MAX_LEN);
596            self.info[self.len()] = MaybeUninit::new(item.0);
597            self.nodes[self.len as usize] = MaybeUninit::new(item.1);
598            // We have just initialized both info and node and 0..=len, so we can increase it
599            self.len += 1;
600        }
601
602        /// Pops an item off the end of the array and returns it.
603        ///
604        /// Decreases length by one.  Panics if already empty.
605        #[inline(always)]
606        pub fn pop(&mut self) -> (TextInfo, Arc<Node>) {
607            assert!(self.len() > 0);
608            self.len -= 1;
609            // SAFETY: before this, len was long enough to guarantee that both must be init
610            // We just decreased the length, guaranteeing that the elements will never be read again
611            (unsafe { self.info[self.len()].assume_init() }, unsafe {
612                ptr::read(&self.nodes[self.len()]).assume_init()
613            })
614        }
615
616        /// Inserts an item into the the array at the given index.
617        ///
618        /// Increases length by one.  Panics if already full.  Preserves ordering
619        /// of the other items.
620        #[inline(always)]
621        pub fn insert(&mut self, idx: usize, item: (TextInfo, Arc<Node>)) {
622            assert!(idx <= self.len());
623            assert!(self.len() < MAX_LEN);
624
625            let len = self.len();
626            // This unsafe code simply shifts the elements of the arrays over
627            // to make space for the new inserted value.  The `.info` array
628            // shifting can be done with a safe call to `copy_within()`.
629            // However, the `.nodes` array shift cannot, because of the
630            // specific drop semantics needed for safety.
631            unsafe {
632                let ptr = self.nodes.as_mut_ptr();
633                ptr::copy(ptr.add(idx), ptr.add(idx + 1), len - idx);
634            }
635            self.info.copy_within(idx..len, idx + 1);
636
637            // We have just made space for the two new elements, so insert them
638            self.info[idx] = MaybeUninit::new(item.0);
639            self.nodes[idx] = MaybeUninit::new(item.1);
640            // Now that all elements from 0..=len are initialized, we can increase the length
641            self.len += 1;
642        }
643
644        /// Removes the item at the given index from the the array.
645        ///
646        /// Decreases length by one.  Preserves ordering of the other items.
647        #[inline(always)]
648        pub fn remove(&mut self, idx: usize) -> (TextInfo, Arc<Node>) {
649            assert!(self.len() > 0);
650            assert!(idx < self.len());
651
652            // Read out the elements, they must not be touched again. We copy the elements
653            // after them into them, and decrease the length at the end
654            let item = (unsafe { self.info[idx].assume_init() }, unsafe {
655                ptr::read(&self.nodes[idx]).assume_init()
656            });
657
658            let len = self.len();
659            // This unsafe code simply shifts the elements of the arrays over
660            // to fill in the gap left by the removed element.  The `.info`
661            // array shifting can be done with a safe call to `copy_within()`.
662            // However, the `.nodes` array shift cannot, because of the
663            // specific drop semantics needed for safety.
664            unsafe {
665                let ptr = self.nodes.as_mut_ptr();
666                ptr::copy(ptr.add(idx + 1), ptr.add(idx), len - idx - 1);
667            }
668            self.info.copy_within((idx + 1)..len, idx);
669
670            // Now that the gap is filled, decrease the length
671            self.len -= 1;
672
673            return item;
674        }
675    }
676
677    impl Drop for NodeChildrenInternal {
678        fn drop(&mut self) {
679            // The `.nodes` array contains `MaybeUninit` wrappers, which need
680            // to be manually dropped if valid.  We drop only the valid ones
681            // here.
682            for node in &mut self.nodes[..self.len as usize] {
683                unsafe { ptr::drop_in_place(node.as_mut_ptr()) };
684            }
685        }
686    }
687
688    impl Clone for NodeChildrenInternal {
689        fn clone(&self) -> NodeChildrenInternal {
690            // Create an empty NodeChildrenInternal first, then fill it
691            let mut clone_array = NodeChildrenInternal::new();
692
693            // Copy nodes... carefully.
694            for (clone_arc, arc) in Iterator::zip(
695                clone_array.nodes[..self.len()].iter_mut(),
696                self.nodes[..self.len()].iter(),
697            ) {
698                *clone_arc = MaybeUninit::new(Arc::clone(unsafe { &*arc.as_ptr() }));
699            }
700
701            // Copy TextInfo
702            for (clone_info, info) in Iterator::zip(
703                clone_array.info[..self.len()].iter_mut(),
704                self.info[..self.len()].iter(),
705            ) {
706                *clone_info = *info;
707            }
708
709            // Set length
710            clone_array.len = self.len;
711
712            // Some sanity checks for debug builds
713            #[cfg(debug_assertions)]
714            {
715                for (a, b) in Iterator::zip(
716                    (&clone_array.info[..clone_array.len()]).iter(),
717                    (&self.info[..self.len()]).iter(),
718                ) {
719                    assert_eq!(unsafe { a.assume_init() }, unsafe { b.assume_init() },);
720                }
721
722                for (a, b) in Iterator::zip(
723                    (&clone_array.nodes[..clone_array.len()]).iter(),
724                    (&self.nodes[..clone_array.len()]).iter(),
725                ) {
726                    assert!(Arc::ptr_eq(unsafe { &*a.as_ptr() }, unsafe {
727                        &*b.as_ptr()
728                    },));
729                }
730            }
731
732            clone_array
733        }
734    }
735}
736
737//===========================================================================
738
739#[cfg(test)]
740mod tests {
741    use super::*;
742    use crate::tree::{Node, NodeText, TextInfo};
743    use std::sync::Arc;
744
745    #[test]
746    fn search_char_idx_01() {
747        let mut children = NodeChildren::new();
748        children.push((
749            TextInfo::new(),
750            Arc::new(Node::Leaf(NodeText::from_str("Hello "))),
751        ));
752        children.push((
753            TextInfo::new(),
754            Arc::new(Node::Leaf(NodeText::from_str("there "))),
755        ));
756        children.push((
757            TextInfo::new(),
758            Arc::new(Node::Leaf(NodeText::from_str("world!"))),
759        ));
760
761        children.update_child_info(0);
762        children.update_child_info(1);
763        children.update_child_info(2);
764
765        assert_eq!(0, children.search_char_idx(0).0);
766        assert_eq!(0, children.search_char_idx(1).0);
767        assert_eq!(0, children.search_char_idx(0).1.chars);
768        assert_eq!(0, children.search_char_idx(1).1.chars);
769
770        assert_eq!(0, children.search_char_idx(5).0);
771        assert_eq!(1, children.search_char_idx(6).0);
772        assert_eq!(0, children.search_char_idx(5).1.chars);
773        assert_eq!(6, children.search_char_idx(6).1.chars);
774
775        assert_eq!(1, children.search_char_idx(11).0);
776        assert_eq!(2, children.search_char_idx(12).0);
777        assert_eq!(6, children.search_char_idx(11).1.chars);
778        assert_eq!(12, children.search_char_idx(12).1.chars);
779
780        assert_eq!(2, children.search_char_idx(17).0);
781        assert_eq!(2, children.search_char_idx(18).0);
782        assert_eq!(12, children.search_char_idx(17).1.chars);
783        assert_eq!(12, children.search_char_idx(18).1.chars);
784    }
785
786    #[test]
787    #[should_panic]
788    #[cfg(debug_assertions)]
789    fn search_char_idx_02() {
790        let mut children = NodeChildren::new();
791        children.push((
792            TextInfo::new(),
793            Arc::new(Node::Leaf(NodeText::from_str("Hello "))),
794        ));
795        children.push((
796            TextInfo::new(),
797            Arc::new(Node::Leaf(NodeText::from_str("there "))),
798        ));
799        children.push((
800            TextInfo::new(),
801            Arc::new(Node::Leaf(NodeText::from_str("world!"))),
802        ));
803
804        children.update_child_info(0);
805        children.update_child_info(1);
806        children.update_child_info(2);
807
808        children.search_char_idx(19);
809    }
810
811    #[test]
812    fn search_char_idx_range_01() {
813        let mut children = NodeChildren::new();
814        children.push((
815            TextInfo::new(),
816            Arc::new(Node::Leaf(NodeText::from_str("Hello "))),
817        ));
818        children.push((
819            TextInfo::new(),
820            Arc::new(Node::Leaf(NodeText::from_str("there "))),
821        ));
822        children.push((
823            TextInfo::new(),
824            Arc::new(Node::Leaf(NodeText::from_str("world!"))),
825        ));
826
827        children.update_child_info(0);
828        children.update_child_info(1);
829        children.update_child_info(2);
830
831        let at_0_0 = children.search_char_idx_range(0, 0);
832        let at_6_6 = children.search_char_idx_range(6, 6);
833        let at_12_12 = children.search_char_idx_range(12, 12);
834        let at_18_18 = children.search_char_idx_range(18, 18);
835
836        assert_eq!(0, (at_0_0.0).0);
837        assert_eq!(0, (at_0_0.1).0);
838        assert_eq!(0, (at_0_0.0).1);
839        assert_eq!(0, (at_0_0.1).1);
840
841        assert_eq!(1, (at_6_6.0).0);
842        assert_eq!(1, (at_6_6.1).0);
843        assert_eq!(6, (at_6_6.0).1);
844        assert_eq!(6, (at_6_6.1).1);
845
846        assert_eq!(2, (at_12_12.0).0);
847        assert_eq!(2, (at_12_12.1).0);
848        assert_eq!(12, (at_12_12.0).1);
849        assert_eq!(12, (at_12_12.1).1);
850
851        assert_eq!(2, (at_18_18.0).0);
852        assert_eq!(2, (at_18_18.1).0);
853        assert_eq!(12, (at_18_18.0).1);
854        assert_eq!(12, (at_18_18.1).1);
855
856        let at_0_6 = children.search_char_idx_range(0, 6);
857        let at_6_12 = children.search_char_idx_range(6, 12);
858        let at_12_18 = children.search_char_idx_range(12, 18);
859
860        assert_eq!(0, (at_0_6.0).0);
861        assert_eq!(0, (at_0_6.1).0);
862        assert_eq!(0, (at_0_6.0).1);
863        assert_eq!(0, (at_0_6.1).1);
864
865        assert_eq!(1, (at_6_12.0).0);
866        assert_eq!(1, (at_6_12.1).0);
867        assert_eq!(6, (at_6_12.0).1);
868        assert_eq!(6, (at_6_12.1).1);
869
870        assert_eq!(2, (at_12_18.0).0);
871        assert_eq!(2, (at_12_18.1).0);
872        assert_eq!(12, (at_12_18.0).1);
873        assert_eq!(12, (at_12_18.1).1);
874
875        let at_5_7 = children.search_char_idx_range(5, 7);
876        let at_11_13 = children.search_char_idx_range(11, 13);
877
878        assert_eq!(0, (at_5_7.0).0);
879        assert_eq!(1, (at_5_7.1).0);
880        assert_eq!(0, (at_5_7.0).1);
881        assert_eq!(6, (at_5_7.1).1);
882
883        assert_eq!(1, (at_11_13.0).0);
884        assert_eq!(2, (at_11_13.1).0);
885        assert_eq!(6, (at_11_13.0).1);
886        assert_eq!(12, (at_11_13.1).1);
887    }
888
889    #[test]
890    #[should_panic]
891    fn search_char_idx_range_02() {
892        let mut children = NodeChildren::new();
893        children.push((
894            TextInfo::new(),
895            Arc::new(Node::Leaf(NodeText::from_str("Hello "))),
896        ));
897        children.push((
898            TextInfo::new(),
899            Arc::new(Node::Leaf(NodeText::from_str("there "))),
900        ));
901        children.push((
902            TextInfo::new(),
903            Arc::new(Node::Leaf(NodeText::from_str("world!"))),
904        ));
905
906        children.update_child_info(0);
907        children.update_child_info(1);
908        children.update_child_info(2);
909
910        children.search_char_idx_range(18, 19);
911    }
912
913    #[test]
914    fn search_line_break_idx_01() {
915        let mut children = NodeChildren::new();
916        children.push((
917            TextInfo::new(),
918            Arc::new(Node::Leaf(NodeText::from_str("Hello\n"))),
919        ));
920        children.push((
921            TextInfo::new(),
922            Arc::new(Node::Leaf(NodeText::from_str("\nthere\n"))),
923        ));
924        children.push((
925            TextInfo::new(),
926            Arc::new(Node::Leaf(NodeText::from_str("world!\n"))),
927        ));
928
929        children.update_child_info(0);
930        children.update_child_info(1);
931        children.update_child_info(2);
932
933        assert_eq!(0, children.search_line_break_idx(0).0);
934        assert_eq!(0, children.search_line_break_idx(0).1.line_breaks);
935
936        assert_eq!(0, children.search_line_break_idx(1).0);
937        assert_eq!(0, children.search_line_break_idx(1).1.line_breaks);
938
939        assert_eq!(1, children.search_line_break_idx(2).0);
940        assert_eq!(1, children.search_line_break_idx(2).1.line_breaks);
941
942        assert_eq!(1, children.search_line_break_idx(3).0);
943        assert_eq!(1, children.search_line_break_idx(3).1.line_breaks);
944
945        assert_eq!(2, children.search_line_break_idx(4).0);
946        assert_eq!(3, children.search_line_break_idx(4).1.line_breaks);
947
948        assert_eq!(2, children.search_line_break_idx(5).0);
949        assert_eq!(3, children.search_line_break_idx(5).1.line_breaks);
950    }
951
952    #[test]
953    fn search_line_break_idx_02() {
954        let mut children = NodeChildren::new();
955        children.push((
956            TextInfo::new(),
957            Arc::new(Node::Leaf(NodeText::from_str("Hello\n"))),
958        ));
959        children.push((
960            TextInfo::new(),
961            Arc::new(Node::Leaf(NodeText::from_str("there"))),
962        ));
963        children.push((
964            TextInfo::new(),
965            Arc::new(Node::Leaf(NodeText::from_str("world!"))),
966        ));
967
968        children.update_child_info(0);
969        children.update_child_info(1);
970        children.update_child_info(2);
971
972        assert_eq!(0, children.search_line_break_idx(0).0);
973        assert_eq!(0, children.search_line_break_idx(0).1.line_breaks);
974
975        assert_eq!(0, children.search_line_break_idx(1).0);
976        assert_eq!(0, children.search_line_break_idx(1).1.line_breaks);
977
978        assert_eq!(2, children.search_line_break_idx(2).0);
979        assert_eq!(1, children.search_line_break_idx(2).1.line_breaks);
980    }
981
982    #[test]
983    fn search_line_break_idx_03() {
984        let mut children = NodeChildren::new();
985        children.push((
986            TextInfo::new(),
987            Arc::new(Node::Leaf(NodeText::from_str(""))),
988        ));
989
990        children.update_child_info(0);
991
992        assert_eq!(0, children.search_line_break_idx(0).0);
993        assert_eq!(0, children.search_line_break_idx(0).1.line_breaks);
994
995        assert_eq!(0, children.search_line_break_idx(1).0);
996        assert_eq!(0, children.search_line_break_idx(1).1.line_breaks);
997    }
998
999    #[test]
1000    #[should_panic]
1001    #[cfg(debug_assertions)]
1002    fn search_line_break_idx_04() {
1003        let mut children = NodeChildren::new();
1004        children.push((
1005            TextInfo::new(),
1006            Arc::new(Node::Leaf(NodeText::from_str(""))),
1007        ));
1008
1009        children.update_child_info(0);
1010
1011        assert_eq!(0, children.search_line_break_idx(0).0);
1012        assert_eq!(0, children.search_line_break_idx(0).1.line_breaks);
1013
1014        assert_eq!(0, children.search_line_break_idx(1).0);
1015        assert_eq!(0, children.search_line_break_idx(1).1.line_breaks);
1016
1017        assert_eq!(0, children.search_line_break_idx(2).0);
1018        assert_eq!(0, children.search_line_break_idx(2).1.line_breaks);
1019    }
1020}