sparql_service/
service_description_parser.rsuse iri_s::IriS;
use srdf::{ok, property_iri, property_values_iri, FocusRDF, PResult, RDFNodeParse, RDFParser};
use std::fmt::Debug;
use crate::{
Dataset, Feature, ResultFormat, ServiceDescription, ServiceDescriptionError, SupportedLanguage,
SD_BASIC_FEDERATED_QUERY_STR, SD_DEFAULT_DATASET, SD_DEREFERENCES_URIS_STR,
SD_EMPTY_GRAPHS_STR, SD_ENDPOINT, SD_FEATURE, SD_REQUIRES_DATASET_STR, SD_RESULT_FORMAT,
SD_SERVICE, SD_SPARQL10_QUERY_STR, SD_SPARQL11_QUERY_STR, SD_SPARQL11_UPDATE_STR,
SD_SUPPORTED_LANGUAGE, SD_UNION_DEFAULT_GRAPH_STR,
};
type Result<A> = std::result::Result<A, ServiceDescriptionError>;
pub struct ServiceDescriptionParser<RDF>
where
RDF: FocusRDF + Debug,
{
rdf_parser: RDFParser<RDF>,
}
impl<RDF> ServiceDescriptionParser<RDF>
where
RDF: FocusRDF + Debug + 'static,
{
pub fn new(rdf: RDF) -> ServiceDescriptionParser<RDF> {
ServiceDescriptionParser {
rdf_parser: RDFParser::new(rdf),
}
}
pub fn parse(&mut self) -> Result<ServiceDescription> {
let service_node = self.rdf_parser.instance_of(&Self::sd_service())?;
let term = RDF::subject_as_term(&service_node);
self.rdf_parser.rdf.set_focus(&term);
let service = Self::service_description().parse_impl(&mut self.rdf_parser.rdf)?;
Ok(service)
}
pub fn service_description() -> impl RDFNodeParse<RDF, Output = ServiceDescription>
where
RDF: FocusRDF + 'static,
{
Self::endpoint().then(|iri| {
Self::supported_language().then(move |supported_language| {
Self::result_format().then({
let iri = iri.clone();
move |result_format| {
Self::feature().then({
let sl = supported_language.clone();
let iri = iri.clone();
move |feature| {
Self::default_dataset().then({
let iri = iri.clone();
let sl = sl.clone();
let result_format = result_format.clone();
move |default_ds| {
let mut sd = ServiceDescription::new(iri.clone());
sd.add_supported_language(&sl);
sd.add_feature(&feature);
sd.add_result_format(&result_format);
sd.add_default_dataset(&default_ds);
ok(&sd)
}
})
}
})
}
})
})
})
}
pub fn default_dataset() -> impl RDFNodeParse<RDF, Output = Dataset>
where
RDF: FocusRDF + 'static,
{
property_iri(&SD_DEFAULT_DATASET).then(move |iri| ok(&Dataset::new(&iri)))
}
pub fn endpoint() -> impl RDFNodeParse<RDF, Output = IriS>
where
RDF: FocusRDF + 'static,
{
property_iri(&SD_ENDPOINT)
}
pub fn feature() -> impl RDFNodeParse<RDF, Output = Vec<Feature>>
where
RDF: FocusRDF,
{
property_values_iri(&SD_FEATURE).flat_map(|ref iris| {
let features = get_features(iris)?;
Ok(features)
})
}
pub fn result_format() -> impl RDFNodeParse<RDF, Output = Vec<ResultFormat>>
where
RDF: FocusRDF,
{
property_values_iri(&SD_RESULT_FORMAT).flat_map(|ref iris| {
let result_format = get_result_formats(iris)?;
Ok(result_format)
})
}
pub fn supported_language() -> impl RDFNodeParse<RDF, Output = Vec<SupportedLanguage>>
where
RDF: FocusRDF,
{
property_values_iri(&SD_SUPPORTED_LANGUAGE).flat_map(|ref iris| {
let langs = get_supported_languages(iris)?;
Ok(langs)
})
}
fn sd_service() -> RDF::Term {
RDF::iri_s2term(&SD_SERVICE)
}
}
fn get_supported_languages(iris: &Vec<IriS>) -> PResult<Vec<SupportedLanguage>> {
let mut res = Vec::new();
for i in iris {
let supported_language = supported_language(i)?;
res.push(supported_language)
}
Ok(res)
}
fn get_features(iris: &Vec<IriS>) -> PResult<Vec<Feature>> {
let mut res = Vec::new();
for i in iris {
let feature = feature(i)?;
res.push(feature)
}
Ok(res)
}
fn get_result_formats(iris: &Vec<IriS>) -> PResult<Vec<ResultFormat>> {
let mut res = Vec::new();
for i in iris {
let res_format = result_format(i)?;
res.push(res_format)
}
Ok(res)
}
fn supported_language(iri: &IriS) -> PResult<SupportedLanguage> {
match iri.as_str() {
SD_SPARQL10_QUERY_STR => Ok(SupportedLanguage::SPARQL10Query),
SD_SPARQL11_QUERY_STR => Ok(SupportedLanguage::SPARQL11Query),
SD_SPARQL11_UPDATE_STR => Ok(SupportedLanguage::SPARQL11Update),
_ => Err(srdf::RDFParseError::Custom {
msg: format!("Unexpected value for supported language: {iri}"),
}),
}
}
fn result_format(iri: &IriS) -> PResult<ResultFormat> {
let rf = match iri.as_str() {
"http://www.w3.org/ns/formats/SPARQL_Results_XML" => ResultFormat::XML,
"http://www.w3.org/ns/formats/JSON-LD" => ResultFormat::JsonLD,
"http://www.w3.org/ns/formats/N-Triples" => ResultFormat::NTriples,
"http://www.w3.org/ns/formats/SPARQL_Results_CSV" => ResultFormat::CSV,
"http://www.w3.org/ns/formats/SPARQL_Results_JSON" => ResultFormat::JSON,
"http://www.w3.org/ns/formats/Turtle" => ResultFormat::Turtle,
"http://www.w3.org/ns/formats/SPARQL_Results_TSV" => ResultFormat::TSV,
"http://www.w3.org/ns/formats/RDF_XML" => ResultFormat::RdfXml,
_ => ResultFormat::Other(iri.clone()),
};
Ok(rf)
}
fn feature(iri: &IriS) -> PResult<Feature> {
match iri.as_str() {
SD_BASIC_FEDERATED_QUERY_STR => Ok(Feature::BasicFederatedQuery),
SD_UNION_DEFAULT_GRAPH_STR => Ok(Feature::UnionDefaultGraph),
SD_EMPTY_GRAPHS_STR => Ok(Feature::EmptyGraphs),
SD_REQUIRES_DATASET_STR => Ok(Feature::RequiresDataset),
SD_DEREFERENCES_URIS_STR => Ok(Feature::DereferencesURIs),
_ => Ok(Feature::Other(iri.clone())),
}
}