rat_text/text_store/
mod.rs

1use crate::grapheme::Grapheme;
2use crate::{Cursor, TextError, TextPosition, TextRange, upos_type};
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 there a line-break at the end of the text?
37    fn has_final_newline(&self) -> bool;
38
39    /// Number of lines.
40    ///
41    /// This counts the number of newline '\n' and adds one
42    /// for the first row. And it adds one more if the last
43    /// line doesn't end with a newline.
44    ///
45    /// `""` -> 1
46    /// `"a"` -> 1
47    /// `"a\n"` -> 2
48    /// `"a\na"` -> 3
49    /// `"a\na\n"` -> 3
50    fn len_lines(&self) -> upos_type;
51
52    /// Length in bytes
53    fn len_bytes(&self) -> usize;
54
55    /// Minimum byte position that has been changed
56    /// since the last call of min_changed().
57    fn cache_validity(&self) -> Option<usize>;
58
59    /// Get content as string.
60    fn string(&self) -> String;
61
62    /// Set content from string.
63    fn set_string(&mut self, t: &str);
64
65    /// Grapheme position to byte position.
66    /// This is the (start,end) position of the single grapheme after pos.
67    ///
68    /// * pos must be a valid position: row <= len_lines, col <= line_width of the row.
69    fn byte_range_at(&self, pos: TextPosition) -> Result<Range<usize>, TextError>;
70
71    /// Grapheme range to byte range.
72    ///
73    /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
74    fn byte_range(&self, range: TextRange) -> Result<Range<usize>, TextError>;
75
76    /// Byte position to grapheme position.
77    /// Returns the position that contains the given byte index.
78    ///
79    /// * byte must <= byte-len.
80    fn byte_to_pos(&self, byte: usize) -> Result<TextPosition, TextError>;
81
82    /// Byte range to grapheme range.
83    ///
84    /// * byte must <= byte-len.
85    fn bytes_to_range(&self, bytes: Range<usize>) -> Result<TextRange, TextError>;
86
87    /// A range of the text as `Cow<str>`.
88    ///
89    /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
90    /// * pos must be inside of range.
91    fn str_slice(&self, range: TextRange) -> Result<Cow<'_, str>, TextError>;
92
93    /// A range of the text as `Cow<str>`.
94    ///
95    /// * range must be valid
96    fn str_slice_byte(&self, range: Range<usize>) -> Result<Cow<'_, str>, TextError>;
97
98    /// Return a cursor over the graphemes of the range, start at the given position.
99    ///
100    /// * range must be a valid byte-range.
101    /// * pos must be inside of range.
102    fn graphemes_byte(
103        &self,
104        range: Range<usize>,
105        pos: usize,
106    ) -> Result<Self::GraphemeIter<'_>, TextError>;
107
108    /// Line as str.
109    ///
110    /// * row must be <= len_lines
111    fn line_at(&self, row: upos_type) -> Result<Cow<'_, str>, TextError>;
112
113    /// Iterate over text-lines, starting at line-offset.
114    ///
115    /// * row must be <= len_lines
116    fn lines_at(&self, row: upos_type) -> Result<impl Iterator<Item = Cow<'_, str>>, TextError>;
117
118    /// Return a line as an iterator over the graphemes.
119    /// This contains the '\n' at the end.
120    ///
121    /// * row must be <= len_lines
122    fn line_graphemes(&self, row: upos_type) -> Result<Self::GraphemeIter<'_>, TextError>;
123
124    /// Line width of row as grapheme count.
125    /// Excludes the terminating '\n'.
126    ///
127    /// * row must be <= len_lines
128    fn line_width(&self, row: upos_type) -> Result<upos_type, TextError>;
129
130    /// Insert a char at the given position.
131    ///
132    /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
133    fn insert_char(
134        &mut self,
135        pos: TextPosition,
136        c: char,
137    ) -> Result<(TextRange, Range<usize>), TextError>;
138
139    /// Insert a text str at the given position.
140    ///
141    /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
142    fn insert_str(
143        &mut self,
144        pos: TextPosition,
145        t: &str,
146    ) -> Result<(TextRange, Range<usize>), TextError>;
147
148    /// Remove the given text range.
149    ///
150    /// * range must be a valid range. row <= len_lines, col <= line_width of the row.
151    fn remove(
152        &mut self,
153        range: TextRange,
154    ) -> Result<(String, (TextRange, Range<usize>)), TextError>;
155
156    /// Insert a string at the given byte index.
157    /// Call this only for undo.
158    ///
159    /// byte_pos must be <= len bytes.
160    fn insert_b(&mut self, byte_pos: usize, t: &str) -> Result<(), TextError>;
161
162    /// Remove the given byte-range.
163    /// Call this only for undo.
164    ///
165    /// byte_pos must be <= len bytes.
166    fn remove_b(&mut self, byte_range: Range<usize>) -> Result<(), TextError>;
167}