use super::service_description_types::{
EntailmentRegime, SdFeature, SdInputFormat, SdLanguage, SdResultFormat, ServiceDescription,
};
#[derive(Debug, Default)]
pub struct ServiceDescriptionBuilder {
pub(super) endpoint_url: String,
pub(super) dataset_name: String,
pub(super) features: Vec<SdFeature>,
pub(super) supported_languages: Vec<SdLanguage>,
pub(super) result_formats: Vec<SdResultFormat>,
pub(super) input_formats: Vec<SdInputFormat>,
pub(super) extension_functions: Vec<String>,
pub(super) entailment_regimes: Vec<EntailmentRegime>,
pub(super) label: Option<String>,
pub(super) description: Option<String>,
}
impl ServiceDescriptionBuilder {
pub fn new(endpoint_url: impl Into<String>, dataset_name: impl Into<String>) -> Self {
ServiceDescriptionBuilder {
endpoint_url: endpoint_url.into(),
dataset_name: dataset_name.into(),
..Default::default()
}
}
pub fn with_feature(mut self, feature: SdFeature) -> Self {
self.features.push(feature);
self
}
pub fn with_features(mut self, features: impl IntoIterator<Item = SdFeature>) -> Self {
self.features.extend(features);
self
}
pub fn with_language(mut self, language: SdLanguage) -> Self {
self.supported_languages.push(language);
self
}
pub fn with_languages(mut self, languages: impl IntoIterator<Item = SdLanguage>) -> Self {
self.supported_languages.extend(languages);
self
}
pub fn with_result_format(mut self, format: SdResultFormat) -> Self {
self.result_formats.push(format);
self
}
pub fn with_result_formats(
mut self,
formats: impl IntoIterator<Item = SdResultFormat>,
) -> Self {
self.result_formats.extend(formats);
self
}
pub fn with_input_format(mut self, format: SdInputFormat) -> Self {
self.input_formats.push(format);
self
}
pub fn with_input_formats(mut self, formats: impl IntoIterator<Item = SdInputFormat>) -> Self {
self.input_formats.extend(formats);
self
}
pub fn with_extension_function(mut self, iri: impl Into<String>) -> Self {
self.extension_functions.push(iri.into());
self
}
pub fn with_extension_functions(mut self, iris: impl IntoIterator<Item = String>) -> Self {
self.extension_functions.extend(iris);
self
}
pub fn with_entailment_regime(mut self, regime: EntailmentRegime) -> Self {
self.entailment_regimes.push(regime);
self
}
pub fn with_label(mut self, label: impl Into<String>) -> Self {
self.label = Some(label.into());
self
}
pub fn with_description(mut self, desc: impl Into<String>) -> Self {
self.description = Some(desc.into());
self
}
pub fn build(self) -> ServiceDescription {
ServiceDescription {
endpoint_url: self.endpoint_url,
dataset_name: self.dataset_name,
features: self.features,
supported_languages: self.supported_languages,
result_formats: self.result_formats,
input_formats: self.input_formats,
extension_functions: self.extension_functions,
entailment_regimes: self.entailment_regimes,
label: self.label,
description: self.description,
}
}
}
impl ServiceDescription {
pub fn builder(
endpoint_url: impl Into<String>,
dataset_name: impl Into<String>,
) -> ServiceDescriptionBuilder {
ServiceDescriptionBuilder::new(endpoint_url, dataset_name)
}
pub fn default_for_oxirs(endpoint_url: &str, dataset_name: &str) -> Self {
ServiceDescriptionBuilder::new(endpoint_url, dataset_name)
.with_label("OxiRS SPARQL Endpoint")
.with_description(
"OxiRS: A Rust-native, JVM-free RDF platform with SPARQL 1.1/1.2 support, \
GraphQL integration, and AI-augmented reasoning.",
)
.with_features([
SdFeature::DereferencesUris,
SdFeature::UnionDefaultGraph,
SdFeature::EmptyGraphs,
SdFeature::BasicFederatedQuery,
SdFeature::RdfStar,
SdFeature::SparqlStar,
])
.with_languages([
SdLanguage::Sparql10Query,
SdLanguage::Sparql11Query,
SdLanguage::Sparql11Update,
SdLanguage::Sparql12Query,
SdLanguage::Sparql12Update,
])
.with_result_formats([
SdResultFormat::SparqlResultsJson,
SdResultFormat::SparqlResultsXml,
SdResultFormat::SparqlResultsCsv,
SdResultFormat::SparqlResultsTsv,
SdResultFormat::Turtle,
SdResultFormat::NTriples,
SdResultFormat::NQuads,
SdResultFormat::TriG,
SdResultFormat::JsonLd,
SdResultFormat::RdfXml,
])
.with_input_formats([
SdInputFormat::Turtle,
SdInputFormat::NTriples,
SdInputFormat::NQuads,
SdInputFormat::TriG,
SdInputFormat::JsonLd,
SdInputFormat::RdfXml,
])
.with_entailment_regime(EntailmentRegime::Simple)
.with_entailment_regime(EntailmentRegime::Rdf)
.with_entailment_regime(EntailmentRegime::Rdfs)
.build()
}
pub fn result_format_count(&self) -> usize {
self.result_formats.len()
}
pub fn input_format_count(&self) -> usize {
self.input_formats.len()
}
pub fn supports_language(&self, language_iri: &str) -> bool {
self.supported_languages
.iter()
.any(|l| l.as_iri() == language_iri)
}
pub fn has_feature(&self, feature_iri: &str) -> bool {
self.features.iter().any(|f| f.as_iri() == feature_iri)
}
pub fn supports_result_mime(&self, mime: &str) -> bool {
self.result_formats.iter().any(|f| f.mime_type() == mime)
}
pub fn accepts_input_mime(&self, mime: &str) -> bool {
self.input_formats.iter().any(|f| f.mime_type() == mime)
}
pub fn supports_sparql11(&self) -> bool {
self.supports_language(SdLanguage::Sparql11Query.as_iri())
}
pub fn supports_sparql12(&self) -> bool {
self.supports_language(SdLanguage::Sparql12Query.as_iri())
}
pub fn supports_update(&self) -> bool {
self.supports_language(SdLanguage::Sparql11Update.as_iri())
|| self.supports_language(SdLanguage::Sparql12Update.as_iri())
}
pub fn supports_entailment(&self, regime: &EntailmentRegime) -> bool {
self.entailment_regimes.contains(regime)
}
pub fn merge(&mut self, other: ServiceDescription) {
for feat in other.features {
if !self.features.contains(&feat) {
self.features.push(feat);
}
}
for lang in other.supported_languages {
if !self.supported_languages.contains(&lang) {
self.supported_languages.push(lang);
}
}
for fmt in other.result_formats {
if !self.result_formats.contains(&fmt) {
self.result_formats.push(fmt);
}
}
for fmt in other.input_formats {
if !self.input_formats.contains(&fmt) {
self.input_formats.push(fmt);
}
}
for iri in other.extension_functions {
if !self.extension_functions.contains(&iri) {
self.extension_functions.push(iri);
}
}
for regime in other.entailment_regimes {
if !self.entailment_regimes.contains(®ime) {
self.entailment_regimes.push(regime);
}
}
}
}