Add Rope::insert_char_at_index()
This commit is contained in:
parent
1164922ffe
commit
c3ebef8fc1
|
|
@ -94,15 +94,33 @@ impl Rope {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn concat(first: Rc<Rope>, second: Rc<Rope>) -> Rc<Rope> {
|
||||
Rope::join(first, Some(second)).rebalance()
|
||||
/// Returns a new rope created from concatenating `other` onto the end of
|
||||
/// this one.
|
||||
pub fn concat(self: Rc<Rope>, other: Rc<Rope>) -> Rc<Rope> {
|
||||
Rope::join(self, Some(other)).rebalance()
|
||||
}
|
||||
|
||||
/// Insert new text into the rope at a given character index.
|
||||
pub fn insert_at_char_index(self: &Rc<Rope>, index: usize, text: impl Into<String>) -> Rc<Rope> {
|
||||
let new_node = Rope::new(text);
|
||||
let total_chars = self.total_chars();
|
||||
if index == 0 {
|
||||
new_node.concat(self.clone())
|
||||
} else if index < total_chars {
|
||||
let (before, after) = self.split_at_char_index(index);
|
||||
before.concat(new_node).concat(after)
|
||||
} else if index == total_chars {
|
||||
self.clone().concat(new_node)
|
||||
} else {
|
||||
panic!("Attempt to insert past end of rope.")
|
||||
}
|
||||
}
|
||||
|
||||
/// Split the rope in two at character `index`.
|
||||
///
|
||||
/// The result is two Ropes—one containing the first 'i' characters of the
|
||||
/// text and the other containing the rest of the text.
|
||||
pub fn split(self: &Rc<Self>, index: usize) -> (Rc<Self>, Rc<Self>) {
|
||||
pub fn split_at_char_index(self: &Rc<Self>, index: usize) -> (Rc<Self>, Rc<Self>) {
|
||||
match *self.as_ref() {
|
||||
Rope::Branch {
|
||||
chars_weight,
|
||||
|
|
@ -111,14 +129,14 @@ impl Rope {
|
|||
..
|
||||
} => {
|
||||
if index < chars_weight {
|
||||
let (first, second) = left.split(index);
|
||||
let (first, second) = left.split_at_char_index(index);
|
||||
(
|
||||
first.rebalance(),
|
||||
Rope::join(second, right.as_ref().map(|r| r.clone())).rebalance(),
|
||||
)
|
||||
} else if let Some(right) = right {
|
||||
if index > chars_weight {
|
||||
let (first, second) = right.split(index - chars_weight);
|
||||
let (first, second) = right.split_at_char_index(index - chars_weight);
|
||||
(
|
||||
Rope::join(left.clone(), Some(first)).rebalance(),
|
||||
second.rebalance(),
|
||||
|
|
@ -430,7 +448,7 @@ mod tests {
|
|||
let target = small_test_rope();
|
||||
let full_string = small_test_rope_full_string();
|
||||
for i in 0..(full_string.chars().count()) {
|
||||
let (first, second) = target.split(i);
|
||||
let (first, second) = target.split_at_char_index(i);
|
||||
let first_string: String = first.iter_chars().collect();
|
||||
let second_string: String = second.iter_chars().collect();
|
||||
assert_eq!(first_string, full_string[0..i]);
|
||||
|
|
@ -446,7 +464,7 @@ mod tests {
|
|||
.chars()
|
||||
.collect();
|
||||
for i in 0..(expected_chars.len()) {
|
||||
let (first, second) = target.split(i);
|
||||
let (first, second) = target.split_at_char_index(i);
|
||||
let string: String = first.iter_chars().collect();
|
||||
let expected: String = expected_chars[0..i].iter().collect();
|
||||
assert_eq!(string, expected);
|
||||
|
|
@ -525,4 +543,19 @@ mod tests {
|
|||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_at_char_index() {
|
||||
let target = Rope::new("The brown dog");
|
||||
assert_eq!(target.iter_chars().collect::<String>(), "The brown dog");
|
||||
let rope1 = target.insert_at_char_index(4, "quick");
|
||||
assert_eq!(target.iter_chars().collect::<String>(), "The brown dog");
|
||||
assert_eq!(rope1.iter_chars().collect::<String>(), "The quickbrown dog");
|
||||
let rope2 = rope1.insert_at_char_index(9, " ");
|
||||
assert_eq!(target.iter_chars().collect::<String>(), "The brown dog");
|
||||
assert_eq!(rope1.iter_chars().collect::<String>(), "The quickbrown dog");
|
||||
assert_eq!(rope2.iter_chars().collect::<String>(), "The quick brown dog");
|
||||
let rope3 = rope2.insert_at_char_index("The quick brown dog".len(), " jumps over the lazy fox.");
|
||||
assert_eq!(rope3.iter_chars().collect::<String>(), "The quick brown dog jumps over the lazy fox.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue