1use std::ops::{Deref, DerefMut};
23/// This is publicly exposed because we need it for the interactive fixing
4/// feature, but should _not_ be considered part of the public API. There are
5/// no guarantees about the stability of this type and its methods.
6#[doc(hidden)]
7#[derive(Debug, Default, Clone, Eq, PartialEq)]
8pub struct Rope(crop::Rope);
910/// This is publicly exposed because we need it for the interactive fixing
11/// feature, but should _not_ be considered part of the public API. There are
12/// no guarantees about the stability of this type and its methods.
13#[doc(hidden)]
14pub use crop::RopeSlice;
1516impl Deref for Rope {
17type Target = crop::Rope;
1819fn deref(&self) -> &Self::Target {
20&self.0
21}
22}
2324impl DerefMut for Rope {
25fn deref_mut(&mut self) -> &mut Self::Target {
26&mut self.0
27}
28}
2930impl From<crop::Rope> for Rope {
31fn from(rope: crop::Rope) -> Self {
32Self(rope)
33 }
34}
3536impl From<Rope> for crop::Rope {
37fn from(rope: Rope) -> Self {
38 rope.0
39}
40}
4142impl From<&str> for Rope {
43fn from(s: &str) -> Self {
44Self(crop::Rope::from(s))
45 }
46}
4748impl From<String> for Rope {
49fn from(s: String) -> Self {
50Self(crop::Rope::from(s))
51 }
52}
5354impl Rope {
55pub fn line_column_of_byte(&self, byte_offset: usize) -> (usize, usize) {
56self.byte_slice(..).line_column_of_byte(byte_offset)
57 }
58}
5960/// This is publicly exposed because we need it for the interactive fixing
61/// feature, but should _not_ be considered part of the public API. There are
62/// no guarantees about the stability of this type and its methods.
63#[doc(hidden)]
64pub trait RopeSliceExt {
65fn eq_str(&self, s: &str) -> bool;
66fn line_column_of_byte(&self, byte_offset: usize) -> (usize, usize);
67}
6869impl RopeSliceExt for RopeSlice<'_> {
70fn eq_str(&self, s: &str) -> bool {
71let mut this = self.bytes();
72let mut s = s.as_bytes().iter();
7374loop {
75match (this.next(), s.next()) {
76 (Some(this_byte), Some(s_byte)) => {
77if this_byte != *s_byte {
78return false;
79 }
80continue;
81 }
82 (None, None) => return true,
83_ => return false,
84 }
85 }
86 }
8788fn line_column_of_byte(&self, byte_offset: usize) -> (usize, usize) {
89let line = self.line_of_byte(byte_offset);
90let start_of_line = self.byte_of_line(line);
91let column = byte_offset - start_of_line;
92 (line, column)
93 }
94}
9596#[cfg(test)]
97mod tests {
98use crate::rope::{Rope, RopeSliceExt as _};
99100#[test]
101fn test_eq_str() {
102let rope = Rope::from("hello world");
103assert!(rope.byte_slice(0..5).eq_str("hello"));
104assert!(rope.byte_slice(6..11).eq_str("world"));
105assert!(rope.byte_slice(..).eq_str("hello world"));
106assert!(!rope.byte_slice(0..4).eq_str("hello"));
107assert!(!rope.byte_slice(0..5).eq_str("world"));
108assert!(!rope.byte_slice(6..11).eq_str("hello worlds"));
109 }
110}