Skip to content

Commit

Permalink
implemented TextSelection.absolute_offset() and textselection_by_offs…
Browse files Browse the repository at this point in the history
…et()
  • Loading branch information
proycon committed Feb 20, 2024
1 parent 3eb3c97 commit 120b476
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/api/textselection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,10 @@ impl<'store> ResultTextSelection<'store> {
}
}

/// Returns the offset of this text selection in another. Returns None if they are not embedded.
/// Returns the offset of this text selection in another, i.e. returning a relative offset. Returns None if they are not embedded.
/// This also checks whether the textselections pertain to the same resource. Returns None otherwise.
///
/// If you want to turn a relative offset into an absolute one, use [`Self.absolute_offset()`].
pub fn relative_offset(
&self,
container: &ResultTextSelection<'store>,
Expand All @@ -214,6 +216,25 @@ impl<'store> ResultTextSelection<'store> {
}
}

/// Converts a relative offset, expressed in the coordinates of this text selection, to an absolute one
/// expressed in the coordinates of the resource.
pub fn absolute_offset(&self, offset: &Offset) -> Result<Offset, StamError> {
match self {
Self::Bound(item) => item.as_ref().absolute_offset(offset),
Self::Unbound(_, _, item) => item.absolute_offset(offset),
}
}

/// Return a textselection by *relative* offset.
/// The offset is relative to the current textselection.
pub fn textselection_by_offset(
&self,
offset: &Offset,
) -> Result<ResultTextSelection<'store>, StamError> {
self.resource()
.textselection_by_offset(&self.absolute_offset(offset)?)
}

pub(crate) fn store(&self) -> &'store TextResource {
match self {
Self::Bound(item) => item.store(),
Expand Down
39 changes: 39 additions & 0 deletions src/textselection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,45 @@ impl TextSelection {
}
}

/// Converts a relative offset, expressed in the coordinates of this text selection, to an absolute one
/// expressed in the coordinates of the resource.
pub fn absolute_offset(&self, offset: &Offset) -> Result<Offset, StamError> {
let textlen = self.end() - self.begin();
let begin = Cursor::BeginAligned(
self.begin()
+ match offset.begin {
Cursor::BeginAligned(x) => x,
Cursor::EndAligned(x) => {
if x.abs() as usize > textlen {
return Err(StamError::CursorOutOfBounds(
offset.begin,
"(textselection_by_offset)",
));
} else {
textlen - (x as usize)
}
}
},
);
let end = Cursor::BeginAligned(
self.begin()
+ match offset.end {
Cursor::BeginAligned(x) => x,
Cursor::EndAligned(x) => {
if x.abs() as usize > textlen {
return Err(StamError::CursorOutOfBounds(
offset.end,
"(textselection_by_offset)",
));
} else {
textlen - (x as usize)
}
}
},
);
Ok(Offset::new(begin, end))
}

/// Resolves a relative cursor to a relative begin aligned cursor, resolving all end-aligned positions
fn beginaligned_cursor(&self, cursor: &Cursor) -> Result<usize, StamError> {
let textlen = self.end() - self.begin();
Expand Down

0 comments on commit 120b476

Please sign in to comment.