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}