Skip to content

Commit

Permalink
Added ResultItem<Annotation>.test() and test_set() methods for higher…
Browse files Browse the repository at this point in the history
… level access to testing spatial relations
  • Loading branch information
proycon committed Feb 23, 2024
1 parent 6b39386 commit 68c0d89
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
43 changes: 42 additions & 1 deletion src/api/annotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ use crate::datakey::DataKey;
use crate::datavalue::DataOperator;
use crate::resources::{TextResource, TextResourceHandle};
use crate::selector::{Selector, SelectorKind};
use crate::textselection::{ResultTextSelection, TextSelectionOperator, TextSelectionSet};
use crate::textselection::{
ResultTextSelection, ResultTextSelectionSet, TestTextSelection, TextSelectionOperator,
TextSelectionSet,
};
use crate::{Filter, FilterMode, TextMode};

impl<'store> FullHandle<Annotation> for ResultItem<'store, Annotation> {
Expand Down Expand Up @@ -215,6 +218,44 @@ impl<'store> ResultItem<'store, Annotation> {
let tset: TextSelectionSet = self.textselections().collect();
tset.as_resultset(self.store()).related_text(operator)
}

/// Returns the text this resources references as a single text selection set.
/// This only works if the resource references text *AND* all text pertains to a single resource.
pub fn textselectionset(&self) -> Option<ResultTextSelectionSet> {
self.try_into().ok()
}

/// Compares whether a particular spatial relation holds between two annotations
/// This only works if both annotations reference text in the same resource.
pub fn test(
&self,
operator: &TextSelectionOperator,
other: &ResultItem<'store, Annotation>,
) -> bool {
if let Some(tset) = self.textselectionset() {
if let Some(tset2) = other.textselectionset() {
if tset.resource() == tset2.resource() && tset.test_set(operator, &tset2) {
return true;
}
}
}
false
}

/// Compares whether a particular spatial relation holds between this annotation and a textselection set.
/// This only works if both annotations reference text in the same resource.
pub fn test_set(
&self,
operator: &TextSelectionOperator,
other: &ResultTextSelectionSet,
) -> bool {
if let Some(tset) = self.textselectionset() {
if tset.resource() == other.resource() && tset.test_set(operator, other) {
return true;
}
}
false
}
}

/// Holds a collection of [`Annotation`] (by reference to an [`AnnotationStore`] and handles). This structure is produced by calling
Expand Down
35 changes: 35 additions & 0 deletions src/api/textselection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1126,3 +1126,38 @@ impl<'store> From<ResultItem<'store, TextResource>> for ResultTextSelection<'sto
resource.to_textselection()
}
}

impl<'store> TryFrom<&ResultItem<'store, Annotation>> for ResultTextSelectionSet<'store> {
type Error = StamError;
fn try_from(annotation: &ResultItem<'store, Annotation>) -> Result<Self, Self::Error> {
let mut invalid = false;
let mut foundresource: Option<TextResourceHandle> = None;
let tset: TextSelectionSet = annotation
.textselections()
.take_while(move |tsel| {
if foundresource.is_some() {
if foundresource.unwrap() == tsel.resource().handle() {
true
} else {
invalid = true;
false
}
} else {
//first item
foundresource = Some(tsel.resource().handle());
true
}
})
.collect();
if invalid {
Err(StamError::NoText(
"conversion Annotation->TextSelectionSet failed: Annotation does not reference any text or text does not pertain to a single resource",
))
} else {
Ok(ResultTextSelectionSet {
tset,
rootstore: annotation.store(),
})
}
}
}

0 comments on commit 68c0d89

Please sign in to comment.