anchor.rs

 1use super::{Buffer, Content};
 2use anyhow::Result;
 3use std::{cmp::Ordering, ops::Range};
 4use sum_tree::Bias;
 5
 6#[derive(Clone, Eq, PartialEq, Debug, Hash)]
 7pub struct Anchor {
 8    pub offset: usize,
 9    pub bias: Bias,
10    pub version: clock::Global,
11}
12
13impl Anchor {
14    pub fn min() -> Self {
15        Self {
16            offset: 0,
17            bias: Bias::Left,
18            version: Default::default(),
19        }
20    }
21
22    pub fn max() -> Self {
23        Self {
24            offset: usize::MAX,
25            bias: Bias::Right,
26            version: Default::default(),
27        }
28    }
29
30    pub fn cmp<'a>(&self, other: &Anchor, buffer: impl Into<Content<'a>>) -> Result<Ordering> {
31        let buffer = buffer.into();
32
33        if self == other {
34            return Ok(Ordering::Equal);
35        }
36
37        let offset_comparison = if self.version == other.version {
38            self.offset.cmp(&other.offset)
39        } else {
40            buffer
41                .full_offset_for_anchor(self)
42                .cmp(&buffer.full_offset_for_anchor(other))
43        };
44
45        Ok(offset_comparison.then_with(|| self.bias.cmp(&other.bias)))
46    }
47
48    pub fn bias_left(&self, buffer: &Buffer) -> Anchor {
49        if self.bias == Bias::Left {
50            self.clone()
51        } else {
52            buffer.anchor_before(self)
53        }
54    }
55
56    pub fn bias_right(&self, buffer: &Buffer) -> Anchor {
57        if self.bias == Bias::Right {
58            self.clone()
59        } else {
60            buffer.anchor_after(self)
61        }
62    }
63}
64
65pub trait AnchorRangeExt {
66    fn cmp<'a>(&self, b: &Range<Anchor>, buffer: impl Into<Content<'a>>) -> Result<Ordering>;
67}
68
69impl AnchorRangeExt for Range<Anchor> {
70    fn cmp<'a>(&self, other: &Range<Anchor>, buffer: impl Into<Content<'a>>) -> Result<Ordering> {
71        let buffer = buffer.into();
72        Ok(match self.start.cmp(&other.start, &buffer)? {
73            Ordering::Equal => other.end.cmp(&self.end, buffer)?,
74            ord @ _ => ord,
75        })
76    }
77}