Skip to content

Commit

Permalink
Implemented AnnotationDataSetBuilder and AnnotationStore.add_dataset()
Browse files Browse the repository at this point in the history
  • Loading branch information
proycon committed Sep 22, 2024
1 parent dcb7aac commit 9273c0c
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 107 deletions.
108 changes: 108 additions & 0 deletions src/annotationdataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,114 @@ impl AnnotationDataSet {
}
}

#[derive(Debug, Default)]
pub struct AnnotationDataSetBuilder<'a> {
/// Public Id
id: Option<String>,

databuilders: Vec<AnnotationDataBuilder<'a>>,

/// Is this annotation dataset stored stand-off in an external file via @include? This holds the filename
filename: Option<String>,
}

impl<'a> AnnotationDataSetBuilder<'a> {
pub fn new() -> Self {
Self::default()
}

/// Associate a public identifier with the resource. Use this to make a new DataSet.
pub fn with_id(mut self, id: impl Into<String>) -> Self {
self.id = Some(id.into());
self
}

/// Set the filename associated with the dataset.
/// It will be loaded from file as long as you leave id unset.
pub fn with_filename(mut self, filename: impl Into<String>) -> Self {
self.filename = Some(filename.into());
self
}

pub fn with_key(mut self, key: impl Into<BuildItem<'a, DataKey>>) -> Self {
let databuilder = AnnotationDataBuilder::new().with_key(key.into());
self.databuilders.push(databuilder);
self
}

pub fn with_key_value(
mut self,
key: impl Into<BuildItem<'a, DataKey>>,
value: impl Into<DataValue>,
) -> Self {
let databuilder = AnnotationDataBuilder::new()
.with_key(key.into())
.with_value(value.into());
self.databuilders.push(databuilder);
self
}

pub fn with_key_value_id(
mut self,
key: impl Into<BuildItem<'a, DataKey>>,
value: impl Into<DataValue>,
id: impl Into<BuildItem<'a, AnnotationData>>,
) -> Self {
let databuilder = AnnotationDataBuilder::new()
.with_key(key.into())
.with_value(value.into())
.with_id(id.into());
self.databuilders.push(databuilder);
self
}

pub fn with_data(mut self, databuilder: AnnotationDataBuilder<'a>) -> Self {
self.databuilders.push(databuilder);
self
}

///Builds a new [`AnnotationDataSet`] from [`AnnotationDataSetBuilder`], consuming the latter
pub(crate) fn build(self, config: Config) -> Result<AnnotationDataSet, StamError> {
debug(&config, || {
format!(
"AnnotationDataSetBuilder::build: id={:?}, filename={:?}, workdir={:?}",
self.id,
self.filename,
config.workdir(),
)
});
let mut dataset = if let Some(id) = self.id {
AnnotationDataSet::new(config).with_id(id)
} else if let Some(filename) = self.filename {
AnnotationDataSet::from_file(filename.as_str(), config)?
} else {
return Err(StamError::OtherError("AnnotationDataSetBuilder.build(): No filename or ID specified for AnnotationDataSet."));
};
for databuilder in self.databuilders {
dataset.build_insert_data(databuilder, true)?;
}
Ok(dataset)
}
}

impl AnnotationStore {
/// Builds and adds an [`AnnotationDataSet']
pub fn with_dataset(mut self, builder: AnnotationDataSetBuilder) -> Result<Self, StamError> {
self.add_dataset(builder)?;
Ok(self)
}

pub fn add_dataset(
&mut self,
builder: AnnotationDataSetBuilder,
) -> Result<AnnotationDataSetHandle, StamError> {
debug(self.config(), || {
format!("AnnotationStore.add_dataset: builder={:?}", builder)
});
self.insert(builder.build(self.new_config())?)
}
}

////////////////////// Deserialisation

#[derive(Debug)]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub use crate::csv::{FromCsv, ToCsv};

pub use annotation::{Annotation, AnnotationBuilder, AnnotationHandle};
pub use annotationdata::{AnnotationData, AnnotationDataBuilder, AnnotationDataHandle};
pub use annotationdataset::{AnnotationDataSet, AnnotationDataSetHandle};
pub use annotationdataset::{AnnotationDataSet, AnnotationDataSetBuilder, AnnotationDataSetHandle};
pub use annotationstore::AnnotationStore;
pub use api::*;
pub use config::{Config, Configurable};
Expand Down
9 changes: 4 additions & 5 deletions src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,9 @@ impl TextResourceBuilder {
self
}

/// Set the filename associated with the resource. This does **NOT** load
/// the resource from file, but merely sets up the association and where to write to.
/// Use [`Self::from_file()`] instead if you want to load from file.
/// Set the filename associated with the resource.
/// If not ID and no text is give, the resource will be loaded from this file.
/// It is assumed to be either STAM JSON (`.json` extension) or plain text.
pub fn with_filename(mut self, filename: impl Into<String>) -> Self {
self.filename = Some(filename.into());
self
Expand All @@ -351,11 +351,10 @@ impl TextResourceBuilder {
pub(crate) fn build(self, config: Config) -> Result<TextResource, StamError> {
debug(&config, || {
format!(
"TextResourceBuilder::build: id={:?}, filename={:?}, workdir={:?}, use_include={}",
"TextResourceBuilder::build: id={:?}, filename={:?}, workdir={:?}",
self.id,
self.filename,
config.workdir(),
config.use_include()
)
});

Expand Down
2 changes: 1 addition & 1 deletion tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ fn test_search_text_regex_single_capture() -> Result<(), StamError> {
let mut store = AnnotationStore::default();
store.add_resource(TextResourceBuilder::new().with_id("testres").with_text(
"I categorically deny any eavesdropping on you and hearing about your triskaidekaphobia.",
));
))?;
let resource = store.resource("testres").or_fail()?;
let mut count = 0;
for result in resource.find_text_regex(
Expand Down
Loading

0 comments on commit 9273c0c

Please sign in to comment.