chisel_common/char/
coords.rs1#![allow(dead_code)]
2use std::cmp::Ordering;
3use std::fmt::{Display, Formatter};
4
5#[derive(Debug, Copy, Clone, PartialEq)]
7pub struct Coords {
8 pub absolute: usize,
10 pub line: usize,
12 pub column: usize,
14}
15
16impl Coords {
18 pub fn from_coords(value: &Coords) -> Self {
20 Coords {
21 line: value.line,
22 column: value.column,
23 absolute: value.absolute,
24 }
25 }
26
27 pub fn from_line(line: usize) -> Self {
29 Coords {
30 absolute: 0,
31 line,
32 column: 0,
33 }
34 }
35
36 pub fn is_before(&self, other: &Coords) -> bool {
38 self < other
39 }
40
41 pub fn is_after(&self, other: &Coords) -> bool {
43 self > other
44 }
45
46 #[inline]
48 pub fn copy_from(&mut self, other: &Coords) {
49 self.line = other.line;
50 self.column = other.column;
51 self.absolute = other.absolute;
52 }
53
54 #[inline]
56 pub fn increment(&mut self) {
57 self.column += 1;
58 self.absolute += 1;
59 }
60
61 #[inline]
63 pub fn decrement(&mut self) {
64 self.column -= 1;
65 self.absolute -= 1;
66 }
67
68 #[inline]
70 pub fn increment_newline(&mut self) {
71 self.column = 0;
72 self.line += 1;
73 self.absolute += 1;
74 }
75
76 #[inline]
78 pub fn copy_increment(&self) -> Self {
79 Coords {
80 line: self.line,
81 column: self.column + 1,
82 absolute: self.absolute + 1,
83 }
84 }
85
86 #[inline]
89 pub fn copy_increment_newline(&self) -> Self {
90 Coords {
91 line: self.line + 1,
92 column: 1,
93 absolute: self.absolute + 1,
94 }
95 }
96
97 #[inline]
100 pub fn copy_decrement(&mut self) -> Self {
101 Coords {
102 line: self.line,
103 column: self.column - 1,
104 absolute: self.absolute - 1,
105 }
106 }
107}
108
109impl Display for Coords {
110 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
111 write!(
112 f,
113 "[abs: {}, line: {}, column: {}]",
114 self.absolute, self.line, self.column
115 )
116 }
117}
118
119impl Default for Coords {
120 fn default() -> Self {
122 Coords {
123 absolute: 0,
124 line: 0,
125 column: 0,
126 }
127 }
128}
129
130impl Eq for Coords {}
131
132impl PartialOrd<Self> for Coords {
133 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
134 match self.absolute.cmp(&other.absolute) {
135 Ordering::Less => Some(Ordering::Less),
136 Ordering::Equal => Some(Ordering::Equal),
137 Ordering::Greater => Some(Ordering::Greater),
138 }
139 }
140}
141
142impl Ord for Coords {
143 fn cmp(&self, other: &Self) -> Ordering {
144 self.absolute.cmp(&other.absolute)
145 }
146}
147
148#[cfg(test)]
149mod test {
150 use crate::char::coords::Coords;
151
152 #[test]
153 fn is_before_behaves_as_you_would_expect() {
154 let c1 = Coords {
155 line: 1,
156 column: 1,
157 absolute: 1,
158 };
159 let c2 = Coords {
160 line: 1,
161 column: 12,
162 absolute: 12,
163 };
164 assert!(c1.is_before(&c2));
165 assert!(!c2.is_before(&c1));
166 }
167
168 #[test]
169 fn is_after_behaves_correctly() {
170 let c1 = Coords {
171 line: 1,
172 column: 1,
173 absolute: 1,
174 };
175 let c2 = Coords {
176 line: 1,
177 column: 12,
178 absolute: 12,
179 };
180 assert!(!c1.is_after(&c2));
181 assert!(c2.is_after(&c1))
182 }
183
184 #[test]
185 fn equality_between_coords() {
186 let c1 = Coords {
187 line: 1,
188 column: 1,
189 absolute: 1,
190 };
191 let c2 = Coords {
192 line: 1,
193 column: 1,
194 absolute: 1,
195 };
196 assert_eq!(c1, c2)
197 }
198
199 #[test]
200 fn inc_works() {
201 let mut c1 = Coords::from_line(1);
202 for _ in 1..=5 {
203 c1 = c1.copy_increment();
204 }
205 assert_eq!(
206 c1,
207 Coords {
208 line: 1,
209 column: 5,
210 absolute: 5
211 }
212 )
213 }
214
215 #[test]
216 fn inc_newline_works() {
217 let mut c1 = Coords::default();
218 let mut c2 = Coords::default();
219 assert_eq!(c1, c2);
220 c1 = c1.copy_increment_newline();
221 assert!(c1 > c2);
222 c2 = c2.copy_increment_newline();
223 assert_eq!(c1, c2)
224 }
225
226 #[test]
227 fn dec_works() {
228 let mut c1 = Coords::from_line(1);
229 for _ in 1..=5 {
230 c1.increment();
231 }
232 for _ in 1..=3 {
233 c1.decrement()
234 }
235 assert_eq!(
236 c1,
237 Coords {
238 line: 1,
239 column: 2,
240 absolute: 2
241 }
242 )
243 }
244
245 #[test]
246 #[should_panic]
247 fn dec_panics() {
248 let mut c1 = Coords::from_line(1);
249 for _ in 1..=5 {
250 c1.increment();
251 }
252 for _ in 1..=6 {
253 c1.decrement()
254 }
255 }
256
257 #[test]
258 fn merge_should_take_all_values_from_source() {
259 let c1 = Coords::default().copy_increment();
260 let mut c2 = Coords::default();
261 c2.copy_from(&c1);
262 assert_eq!(c1, c2)
263 }
264}