1use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
10
11use serde::{Deserialize, Serialize};
12
13use super::Item;
14
15#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
19pub struct Point {
20 b: u32,
21 c: u32,
22 l: u32,
23}
24
25impl Point {
26 pub fn new() -> Self {
30 Self::default()
31 }
32
33 pub(super) fn from_raw(b: usize, c: usize, l: usize) -> Self {
35 let (b, c, l) = (b as u32, c as u32, l as u32);
36 Self { b, c, l }
37 }
38
39 pub fn len_of(str: impl AsRef<str>) -> Self {
50 let str = str.as_ref();
51 Self {
52 b: str.len() as u32,
53 c: str.chars().count() as u32,
54 l: str.bytes().filter(|c| *c == b'\n').count() as u32,
55 }
56 }
57
58 pub fn byte(&self) -> usize {
61 self.b as usize
62 }
63
64 pub fn char(&self) -> usize {
67 self.c as usize
68 }
69
70 pub fn line(&self) -> usize {
72 self.l as usize
73 }
74
75 pub fn checked_sub(self, rhs: Point) -> Option<Point> {
76 Some(Self {
77 b: self.b.checked_sub(rhs.b)?,
78 c: self.c.checked_sub(rhs.c)?,
79 l: self.l.checked_sub(rhs.l)?,
80 })
81 }
82
83 pub(crate) fn fwd(self, char: char) -> Self {
87 Self {
88 b: self.b + char.len_utf8() as u32,
89 c: self.c + 1,
90 l: self.l + (char == '\n') as u32,
91 }
92 }
93
94 pub(crate) fn rev(self, char: char) -> Self {
96 Self {
97 b: self.b - char.len_utf8() as u32,
98 c: self.c - 1,
99 l: self.l - (char == '\n') as u32,
100 }
101 }
102
103 pub(crate) fn shift_by(self, (b, c, l): (i32, i32, i32)) -> Self {
107 Self {
108 b: (self.b as i32 + b) as u32,
109 c: (self.c as i32 + c) as u32,
110 l: (self.l as i32 + l) as u32,
111 }
112 }
113}
114
115impl std::fmt::Debug for Point {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 write!(f, "Point {{ b: {}, c: {}, l: {} }}", self.b, self.c, self.l)
118 }
119}
120
121impl std::fmt::Display for Point {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 write!(f, "{}, {}, {}", self.b, self.c, self.l)
124 }
125}
126
127impl std::ops::Add for Point {
128 type Output = Self;
129
130 fn add(self, rhs: Self) -> Self::Output {
131 Self {
132 b: self.b + rhs.b,
133 c: self.c + rhs.c,
134 l: self.l + rhs.l,
135 }
136 }
137}
138
139impl std::ops::AddAssign for Point {
140 fn add_assign(&mut self, rhs: Self) {
141 *self = *self + rhs;
142 }
143}
144
145impl std::ops::Sub for Point {
146 type Output = Self;
147
148 fn sub(self, rhs: Self) -> Self::Output {
149 Self {
150 b: self.b - rhs.b,
151 c: self.c - rhs.c,
152 l: self.l - rhs.l,
153 }
154 }
155}
156
157impl std::ops::SubAssign for Point {
158 fn sub_assign(&mut self, rhs: Self) {
159 *self = *self - rhs;
160 }
161}
162
163#[inline]
166pub const fn utf8_char_width(b: u8) -> u32 {
167 const UTF8_CHAR_WIDTH: &[u8; 256] = &[
169 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
187
188 UTF8_CHAR_WIDTH[b as usize] as u32
189}
190
191pub trait TextRange {
216 fn to_range_fwd(self, max: usize) -> Range<usize>;
220
221 fn to_range_rev(self, max: usize) -> Range<usize>;
225
226 fn to_range_at(self, max: usize) -> Range<usize>;
230}
231
232impl TextRange for usize {
233 fn to_range_fwd(self, max: usize) -> Range<usize> {
234 self.min(max)..max
235 }
236
237 fn to_range_rev(self, max: usize) -> Range<usize> {
238 max..self.min(max)
239 }
240
241 fn to_range_at(self, max: usize) -> Range<usize> {
242 self.min(max)..(self + 1).min(max)
243 }
244}
245
246impl TextRange for Range<usize> {
247 fn to_range_fwd(self, max: usize) -> Range<usize> {
248 self.start.min(max)..self.end.min(max)
249 }
250
251 fn to_range_rev(self, max: usize) -> Range<usize> {
252 self.start.min(max)..self.end.min(max)
253 }
254
255 fn to_range_at(self, max: usize) -> Range<usize> {
256 self.start.min(max)..self.end.min(max)
257 }
258}
259
260impl TextRange for RangeInclusive<usize> {
261 fn to_range_fwd(self, max: usize) -> Range<usize> {
262 max.min(*self.start())..max.min(self.end() + 1)
263 }
264
265 fn to_range_rev(self, max: usize) -> Range<usize> {
266 max.min(*self.start())..max.min(self.end() + 1)
267 }
268
269 fn to_range_at(self, max: usize) -> Range<usize> {
270 max.min(*self.start())..max.min(self.end() + 1)
271 }
272}
273
274impl TextRange for RangeTo<usize> {
275 fn to_range_fwd(self, max: usize) -> Range<usize> {
276 0..max.min(self.end)
277 }
278
279 fn to_range_rev(self, max: usize) -> Range<usize> {
280 0..max.min(self.end)
281 }
282
283 fn to_range_at(self, max: usize) -> Range<usize> {
284 0..max.min(self.end)
285 }
286}
287
288impl TextRange for RangeToInclusive<usize> {
289 fn to_range_fwd(self, max: usize) -> Range<usize> {
290 0..max.min(self.end + 1)
291 }
292
293 fn to_range_rev(self, max: usize) -> Range<usize> {
294 0..max.min(self.end + 1)
295 }
296
297 fn to_range_at(self, max: usize) -> Range<usize> {
298 0..max.min(self.end + 1)
299 }
300}
301
302impl TextRange for RangeFrom<usize> {
303 fn to_range_fwd(self, max: usize) -> Range<usize> {
304 max.min(self.start)..max
305 }
306
307 fn to_range_rev(self, max: usize) -> Range<usize> {
308 max.min(self.start)..max
309 }
310
311 fn to_range_at(self, max: usize) -> Range<usize> {
312 max.min(self.start)..max
313 }
314}
315
316impl TextRange for RangeFull {
317 fn to_range_fwd(self, max: usize) -> Range<usize> {
318 0..max
319 }
320
321 fn to_range_rev(self, max: usize) -> Range<usize> {
322 0..max
323 }
324
325 fn to_range_at(self, max: usize) -> Range<usize> {
326 0..max
327 }
328}
329
330impl TextRange for Point {
331 fn to_range_fwd(self, max: usize) -> Range<usize> {
332 self.byte().min(max)..max
333 }
334
335 fn to_range_rev(self, max: usize) -> Range<usize> {
336 0..self.byte().min(max)
337 }
338
339 fn to_range_at(self, max: usize) -> Range<usize> {
340 self.byte().min(max)..(self.byte() + 1).min(max)
341 }
342}
343
344impl TextRange for (Point, Point) {
345 fn to_range_fwd(self, max: usize) -> Range<usize> {
346 self.0.byte().min(max)..self.1.byte().min(max)
347 }
348
349 fn to_range_rev(self, max: usize) -> Range<usize> {
350 self.0.byte().min(max)..self.1.byte().min(max)
351 }
352
353 fn to_range_at(self, max: usize) -> Range<usize> {
354 self.0.byte().min(max)..self.1.byte().min(max)
355 }
356}
357
358impl TextRange for (Option<Point>, Option<Point>) {
359 fn to_range_fwd(self, max: usize) -> Range<usize> {
360 match self {
361 (None, None) => (..).to_range_fwd(max),
362 (None, Some(end)) => (..end.byte()).to_range_fwd(max),
363 (Some(start), None) => (start.byte()..).to_range_fwd(max),
364 (Some(start), Some(end)) => (start.byte()..end.byte()).to_range_fwd(max),
365 }
366 }
367
368 fn to_range_rev(self, max: usize) -> Range<usize> {
369 match self {
370 (None, None) => (..).to_range_rev(max),
371 (None, Some(end)) => (..end.byte()).to_range_rev(max),
372 (Some(start), None) => (start.byte()..).to_range_rev(max),
373 (Some(start), Some(end)) => (start.byte()..end.byte()).to_range_rev(max),
374 }
375 }
376
377 fn to_range_at(self, max: usize) -> Range<usize> {
378 match self {
379 (None, None) => (..).to_range_rev(max),
380 (None, Some(end)) => (..end.byte()).to_range_rev(max),
381 (Some(start), None) => (start.byte()..).to_range_rev(max),
382 (Some(start), Some(end)) => (start.byte()..end.byte()).to_range_rev(max),
383 }
384 }
385}
386
387impl TextRange for (Point, Option<Point>) {
388 fn to_range_fwd(self, max: usize) -> Range<usize> {
389 match self {
390 (start, None) => (start.byte()..).to_range_fwd(max),
391 (start, Some(end)) => (start.byte()..end.byte()).to_range_fwd(max),
392 }
393 }
394
395 fn to_range_rev(self, max: usize) -> Range<usize> {
396 match self {
397 (start, None) => (start.byte()..).to_range_rev(max),
398 (start, Some(end)) => (start.byte()..end.byte()).to_range_rev(max),
399 }
400 }
401
402 fn to_range_at(self, max: usize) -> Range<usize> {
403 match self {
404 (start, None) => (start.byte()..).to_range_rev(max),
405 (start, Some(end)) => (start.byte()..end.byte()).to_range_rev(max),
406 }
407 }
408}
409
410impl TextRange for (Option<Point>, Point) {
411 fn to_range_fwd(self, max: usize) -> Range<usize> {
412 match self {
413 (None, end) => (..end.byte()).to_range_fwd(max),
414 (Some(start), end) => (start.byte()..end.byte()).to_range_fwd(max),
415 }
416 }
417
418 fn to_range_rev(self, max: usize) -> Range<usize> {
419 match self {
420 (None, end) => (..end.byte()).to_range_rev(max),
421 (Some(start), end) => (start.byte()..end.byte()).to_range_rev(max),
422 }
423 }
424
425 fn to_range_at(self, max: usize) -> Range<usize> {
426 match self {
427 (None, end) => (..end.byte()).to_range_rev(max),
428 (Some(start), end) => (start.byte()..end.byte()).to_range_rev(max),
429 }
430 }
431}
432
433pub trait TwoPoints: Clone + Copy {
443 fn to_points(self) -> (Point, Option<Point>);
445}
446
447impl TwoPoints for Point {
448 fn to_points(self) -> (Point, Option<Point>) {
449 (self, None)
450 }
451}
452
453impl TwoPoints for (Point, Point) {
454 fn to_points(self) -> (Point, Option<Point>) {
455 (self.0, Some(self.1))
456 }
457}
458
459impl TwoPoints for (Point, Option<Point>) {
460 fn to_points(self) -> (Point, Option<Point>) {
461 self
462 }
463}
464
465impl TwoPoints for Item {
466 fn to_points(self) -> (Point, Option<Point>) {
467 (self.real, self.ghost)
468 }
469}