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}