rat_text/text_store/mod.rs
1use crate::grapheme::Grapheme;
2use crate::{upos_type, Cursor, TextError, TextPosition, TextRange};
3use std::borrow::Cow;
4use std::ops::Range;
5
6pub(crate) mod text_rope;
7pub(crate) mod text_string;
8
9/// Extended Iterator that can skip over parts of
10/// the underlying data.
11pub trait SkipLine: Iterator {
12 /// Set the iterator to the start of the next line.
13 fn skip_line(&mut self) -> Result<(), TextError>;
14
15 /// Set the iterator to this byte-position.
16 ///
17 /// This is a byte position for the underlying complete
18 /// text, not an index into the iterated slice.
19 /// Nevertheless, the byte_pos must not exceed the
20 /// bounds of the slice.
21 ///
22 /// May panic if this is not a char boundary.
23 /// May panic if the offset is not within the slice-bounds.
24 fn skip_to(&mut self, byte_pos: usize) -> Result<(), TextError>;
25}
26
27/// Backing store for the TextCore.
28pub trait TextStore {
29 type GraphemeIter<'a>: Cursor<Item = Grapheme<'a>> + SkipLine + Clone
30 where
31 Self: 'a;
32
33 /// Can store multi-line content?
34 fn is_multi_line(&self) -> bool;
35
36 /// Is this the special EOT position, and does the line
37 /// before NOT end with a newline?
38 fn should_insert_newline(&self, pos: TextPosition) -> bool;
39
40 /// Number of lines.
41 ///
42 /// This counts the number of newline '\n' and adds one
43 /// for the first row. And it adds one more if the last
44 /// line doesn't end with a newline.
45 ///
46 /// `""` -> 1
47 /// `"a"` -> 1
48 /// `"a\n"` -> 2
49 /// `"a\na"` -> 3
50 /// `"a\na\n"` -> 3
51 fn len_lines(&self) -> upos_type;
52
53 /// Minimum byte position that has been changed
54 /// since the last call of min_changed().
55 fn cache_validity(&self) -> Option<usize>;
56
57 /// Get content as string.
58 fn string(&self) -> String;
59
60 /// Set content from string.
61 fn set_string(&mut self, t: &str);
62
63 /// Grapheme position to byte position.
64 /// This is the (start,end) position of the single grapheme after pos.
65 ///
66 /// * pos must be a valid position: row <= len_lines, col <= line_width of the row.
67 fn byte_range_at(&self, pos: TextPosition) -> Result<Range<usize>, TextError>;
68
69 /// Grapheme range to byte range.
70 ///
71 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
72 fn byte_range(&self, range: TextRange) -> Result<Range<usize>, TextError>;
73
74 /// Byte position to grapheme position.
75 /// Returns the position that contains the given byte index.
76 ///
77 /// * byte must <= byte-len.
78 fn byte_to_pos(&self, byte: usize) -> Result<TextPosition, TextError>;
79
80 /// Byte range to grapheme range.
81 ///
82 /// * byte must <= byte-len.
83 fn bytes_to_range(&self, bytes: Range<usize>) -> Result<TextRange, TextError>;
84
85 /// A range of the text as `Cow<str>`.
86 ///
87 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
88 /// * pos must be inside of range.
89 fn str_slice(&self, range: TextRange) -> Result<Cow<'_, str>, TextError>;
90
91 /// A range of the text as `Cow<str>`.
92 ///
93 /// * range must be valid
94 fn str_slice_byte(&self, range: Range<usize>) -> Result<Cow<'_, str>, TextError>;
95
96 /// Return a cursor over the graphemes of the range, start at the given position.
97 ///
98 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
99 /// * pos must be inside of range.
100 #[deprecated(since = "1.1.0", note = "replaced by grapheme_bytes")]
101 fn graphemes(
102 &self,
103 range: TextRange,
104 pos: TextPosition,
105 ) -> Result<Self::GraphemeIter<'_>, TextError>;
106
107 /// Return a cursor over the graphemes of the range, start at the given position.
108 ///
109 /// * range must be a valid byte-range.
110 /// * pos must be inside of range.
111 fn graphemes_byte(
112 &self,
113 range: Range<usize>,
114 pos: usize,
115 ) -> Result<Self::GraphemeIter<'_>, TextError>;
116
117 /// Line as str.
118 ///
119 /// * row must be <= len_lines
120 fn line_at(&self, row: upos_type) -> Result<Cow<'_, str>, TextError>;
121
122 /// Iterate over text-lines, starting at line-offset.
123 ///
124 /// * row must be <= len_lines
125 fn lines_at(&self, row: upos_type) -> Result<impl Iterator<Item = Cow<'_, str>>, TextError>;
126
127 /// Return a line as an iterator over the graphemes.
128 /// This contains the '\n' at the end.
129 ///
130 /// * row must be <= len_lines
131 fn line_graphemes(&self, row: upos_type) -> Result<Self::GraphemeIter<'_>, TextError>;
132
133 /// Line width of row as grapheme count.
134 /// Excludes the terminating '\n'.
135 ///
136 /// * row must be <= len_lines
137 fn line_width(&self, row: upos_type) -> Result<upos_type, TextError>;
138
139 /// Insert a char at the given position.
140 ///
141 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
142 fn insert_char(
143 &mut self,
144 pos: TextPosition,
145 c: char,
146 ) -> Result<(TextRange, Range<usize>), TextError>;
147
148 /// Insert a text str at the given position.
149 ///
150 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
151 fn insert_str(
152 &mut self,
153 pos: TextPosition,
154 t: &str,
155 ) -> Result<(TextRange, Range<usize>), TextError>;
156
157 /// Remove the given text range.
158 ///
159 /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
160 fn remove(
161 &mut self,
162 range: TextRange,
163 ) -> Result<(String, (TextRange, Range<usize>)), TextError>;
164
165 /// Insert a string at the given byte index.
166 /// Call this only for undo.
167 ///
168 /// byte_pos must be <= len bytes.
169 fn insert_b(&mut self, byte_pos: usize, t: &str) -> Result<(), TextError>;
170
171 /// Remove the given byte-range.
172 /// Call this only for undo.
173 ///
174 /// byte_pos must be <= len bytes.
175 fn remove_b(&mut self, byte_range: Range<usize>) -> Result<(), TextError>;
176}