-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from nomad/anchor-conversion
Add `Replica::create_anchor()` and `Replica::resolve_anchor()`
- Loading branch information
Showing
8 changed files
with
632 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
use crate::*; | ||
|
||
/// A stable reference to a position in a [`Replica`]. | ||
/// | ||
/// After its creation, an `Anchor` can be given to a `Replica` to | ||
/// retrieve the current offset of the position it refers to, taking into | ||
/// account all the edits that have been applied to the `Replica` in the | ||
/// meantime. | ||
/// | ||
/// This property makes `Anchor`s useful to implement things like cursors and | ||
/// selections in collaborative editing environments. | ||
// | ||
/// For more information, see the documentation of | ||
/// [`Replica::create_anchor()`][crate::Replica::create_anchor] and | ||
/// [`Replica::resolve_anchor()`][crate::Replica::resolve_anchor]. | ||
#[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
#[cfg_attr( | ||
any(feature = "encode", feature = "serde"), | ||
derive(serde::Serialize, serde::Deserialize) | ||
)] | ||
pub struct Anchor { | ||
/// TODO: docs | ||
inner: InnerAnchor, | ||
|
||
bias: AnchorBias, | ||
} | ||
|
||
impl Anchor { | ||
#[inline(always)] | ||
pub(crate) fn bias(&self) -> AnchorBias { | ||
self.bias | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn end_of_document() -> Self { | ||
Self::new(InnerAnchor::zero(), AnchorBias::Right) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn inner(&self) -> InnerAnchor { | ||
self.inner | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn is_end_of_document(&self) -> bool { | ||
self.inner.is_zero() && self.bias == AnchorBias::Right | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn is_start_of_document(&self) -> bool { | ||
self.inner.is_zero() && self.bias == AnchorBias::Left | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn new(inner: InnerAnchor, bias: AnchorBias) -> Self { | ||
Self { inner, bias } | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn start_of_document() -> Self { | ||
Self::new(InnerAnchor::zero(), AnchorBias::Left) | ||
} | ||
} | ||
|
||
/// TODO: docs | ||
#[derive(Copy, Clone, PartialEq, Eq)] | ||
#[cfg_attr( | ||
any(feature = "encode", feature = "serde"), | ||
derive(serde::Serialize, serde::Deserialize) | ||
)] | ||
pub(crate) struct InnerAnchor { | ||
/// TODO: docs | ||
replica_id: ReplicaId, | ||
|
||
/// The [`RunTs`] of the [`EditRun`] containing this [`Anchor`]. | ||
contained_in: RunTs, | ||
|
||
/// TODO: docs | ||
offset: Length, | ||
} | ||
|
||
impl core::fmt::Debug for InnerAnchor { | ||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { | ||
if self == &Self::zero() { | ||
write!(f, "zero") | ||
} else { | ||
write!(f, "{:x}.{}", self.replica_id, self.offset) | ||
} | ||
} | ||
} | ||
|
||
impl InnerAnchor { | ||
#[inline(always)] | ||
pub(crate) fn is_zero(&self) -> bool { | ||
self.replica_id == 0 | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn new( | ||
replica_id: ReplicaId, | ||
offset: Length, | ||
run_ts: RunTs, | ||
) -> Self { | ||
Self { replica_id, offset, contained_in: run_ts } | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn offset(&self) -> Length { | ||
self.offset | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn replica_id(&self) -> ReplicaId { | ||
self.replica_id | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn run_ts(&self) -> RunTs { | ||
self.contained_in | ||
} | ||
|
||
/// A special value used to create an anchor at the start of the document. | ||
#[inline] | ||
pub const fn zero() -> Self { | ||
Self { replica_id: 0, offset: 0, contained_in: 0 } | ||
} | ||
} | ||
|
||
/// A bias to use when creating an [`Anchor`]. | ||
/// | ||
/// This is used in the | ||
/// [`Replica::create_anchor()`][crate::Replica::create_anchor] method to | ||
/// create a new [`Anchor`]. See the documentation of that method for more | ||
/// information. | ||
#[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
#[cfg_attr( | ||
any(feature = "encode", feature = "serde"), | ||
derive(serde::Serialize, serde::Deserialize) | ||
)] | ||
pub enum AnchorBias { | ||
/// The anchor should attach to the left. | ||
Left, | ||
|
||
/// The anchor should attach to the right. | ||
Right, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.