Always represent anchor as a versioned offset

Remove the `Start` and `End` variants, and always
use the structure that was previously called `Middle`.
This makes Anchors simpler to serialize and deserialize.
This commit is contained in:
Max Brunsfeld
2021-06-25 17:02:48 -07:00
parent b9952bad8b
commit 60ee97be24
4 changed files with 91 additions and 155 deletions
+36 -45
View File
@@ -4,67 +4,58 @@ use anyhow::Result;
use std::{cmp::Ordering, ops::Range};
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
pub enum Anchor {
Start,
End,
Middle {
offset: usize,
bias: Bias,
version: time::Global,
},
pub struct Anchor {
pub offset: usize,
pub bias: Bias,
pub version: time::Global,
}
impl Anchor {
pub fn min() -> Self {
Self {
offset: 0,
bias: Bias::Left,
version: Default::default(),
}
}
pub fn max() -> Self {
Self {
offset: usize::MAX,
bias: Bias::Right,
version: Default::default(),
}
}
pub fn cmp(&self, other: &Anchor, buffer: &Buffer) -> Result<Ordering> {
if self == other {
return Ok(Ordering::Equal);
}
Ok(match (self, other) {
(Anchor::Start, _) | (_, Anchor::End) => Ordering::Less,
(Anchor::End, _) | (_, Anchor::Start) => Ordering::Greater,
(
Anchor::Middle {
offset: self_offset,
bias: self_bias,
version: self_version,
},
Anchor::Middle {
offset: other_offset,
bias: other_bias,
version: other_version,
},
) => {
let offset_comparison = if self_version == other_version {
self_offset.cmp(other_offset)
} else {
buffer
.full_offset_for_anchor(self)
.cmp(&buffer.full_offset_for_anchor(other))
};
let offset_comparison = if self.version == other.version {
self.offset.cmp(&other.offset)
} else {
buffer
.full_offset_for_anchor(self)
.cmp(&buffer.full_offset_for_anchor(other))
};
offset_comparison.then_with(|| self_bias.cmp(&other_bias))
}
})
Ok(offset_comparison.then_with(|| self.bias.cmp(&other.bias)))
}
pub fn bias_left(&self, buffer: &Buffer) -> Anchor {
match self {
Anchor::Start
| Anchor::Middle {
bias: Bias::Left, ..
} => self.clone(),
_ => buffer.anchor_before(self),
if self.bias == Bias::Left {
self.clone()
} else {
buffer.anchor_before(self)
}
}
pub fn bias_right(&self, buffer: &Buffer) -> Anchor {
match self {
Anchor::End
| Anchor::Middle {
bias: Bias::Right, ..
} => self.clone(),
_ => buffer.anchor_after(self),
if self.bias == Bias::Right {
self.clone()
} else {
buffer.anchor_after(self)
}
}
}