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:
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user