1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/// Generate implementation of common methods shared between
/// both Rope variants (rope & src_rope).
macro_rules! impl_rope {
($ty: ty) => {
impl $ty {
pub fn len(&self) -> usize {
self.len
}
pub fn insert_copy(&mut self, start: usize, text: &str) {
// FIXME If we did clever things with allocation, we could do better here.
self.insert(start, text.to_string());
}
pub fn push(&mut self, text: String) {
let len = self.len();
self.insert(len, text);
}
pub fn push_copy(&mut self, text: &str) {
// If we did clever things with allocation, we could do better here
let len = self.len();
self.insert(len, text.to_string());
}
fn remove_inner<F>(&mut self,
start: usize,
end: usize,
do_remove: F)
where F: Fn(&mut Rope) -> NodeAction
{
assert!(end >= start);
if start == end {
return;
}
match do_remove(self) {
NodeAction::None => {}
NodeAction::Remove => {
self.root = Node::empty_inner();
self.len = 0;
}
NodeAction::Adjust(adj) => self.len = (self.len as isize + adj) as usize,
NodeAction::Change(node, adj) => {
self.root = *node;
self.len = (self.len as isize + adj) as usize;
}
}
}
// This can go horribly wrong if you overwrite a grapheme of different size.
// It is the callers responsibility to ensure that the grapheme at point start
// has the same size as new_char.
pub fn replace(&mut self, start: usize, new_char: char) {
assert!(start + new_char.len_utf8() <= self.len);
// This is pretty wasteful in that we're allocating for no point, but
// I think that is better than duplicating a bunch of code.
// It should be possible to view a &char as a &[u8] somehow, and then
// we can optimise this (FIXME).
self.replace_str(start, &new_char.to_string()[..]);
}
pub fn replace_str(&mut self, start: usize, new_str: &str) {
assert!(start + new_str.len() <= self.len);
self.root.replace(start, new_str);
}
pub fn slice(&self, Range { start, end }: Range<usize>) -> RopeSlice {
// This could be true for two cases
// 1. The Rope is empty (start == end == self.len == 0)
// 2. Attempting to slice the end of the rope (start == end == self.len)
if start == end {
return RopeSlice::empty();
}
debug_assert!(end > start && start <= self.len && end <= self.len);
let mut result = RopeSlice::empty();
self.root.find_slice(start, end, &mut result);
result
}
pub fn full_slice(&self) -> RopeSlice {
self.slice(0..self.len)
}
pub fn chars(&self) -> RopeChars {
RopeChars {
data: self.full_slice(),
cur_node: 0,
cur_byte: 0,
abs_byte: 0,
}
}
}
}
}