sparql_service/
service_description_parser.rs

1use iri_s::IriS;
2use srdf::{ok, property_iri, property_values_iri, FocusRDF, PResult, RDFNodeParse, RDFParser};
3use std::fmt::Debug;
4
5use crate::{
6    Dataset, Feature, ResultFormat, ServiceDescription, ServiceDescriptionError, SupportedLanguage,
7    SD_BASIC_FEDERATED_QUERY_STR, SD_DEFAULT_DATASET, SD_DEREFERENCES_URIS_STR,
8    SD_EMPTY_GRAPHS_STR, SD_ENDPOINT, SD_FEATURE, SD_REQUIRES_DATASET_STR, SD_RESULT_FORMAT,
9    SD_SERVICE, SD_SPARQL10_QUERY_STR, SD_SPARQL11_QUERY_STR, SD_SPARQL11_UPDATE_STR,
10    SD_SUPPORTED_LANGUAGE, SD_UNION_DEFAULT_GRAPH_STR,
11};
12
13type Result<A> = std::result::Result<A, ServiceDescriptionError>;
14
15pub struct ServiceDescriptionParser<RDF>
16where
17    RDF: FocusRDF + Debug,
18{
19    rdf_parser: RDFParser<RDF>,
20}
21
22impl<RDF> ServiceDescriptionParser<RDF>
23where
24    RDF: FocusRDF + Debug + 'static,
25{
26    pub fn new(rdf: RDF) -> ServiceDescriptionParser<RDF> {
27        ServiceDescriptionParser {
28            rdf_parser: RDFParser::new(rdf),
29        }
30    }
31
32    pub fn parse(&mut self) -> Result<ServiceDescription> {
33        let service_node = self.rdf_parser.instance_of(&Self::sd_service())?;
34        let term = service_node.into();
35        self.rdf_parser.rdf.set_focus(&term);
36        let service = Self::service_description().parse_impl(&mut self.rdf_parser.rdf)?;
37        Ok(service)
38    }
39
40    pub fn service_description() -> impl RDFNodeParse<RDF, Output = ServiceDescription>
41    where
42        RDF: FocusRDF + 'static,
43    {
44        Self::endpoint().then(|iri| {
45            Self::supported_language().then(move |supported_language| {
46                Self::result_format().then({
47                    let iri = iri.clone();
48                    move |result_format| {
49                        Self::feature().then({
50                            let sl = supported_language.clone();
51                            let iri = iri.clone();
52                            move |feature| {
53                                Self::default_dataset().then({
54                                    // TODO: There is something ugly here with so many clone()'s...refactor!!
55                                    let iri = iri.clone();
56                                    let sl = sl.clone();
57                                    let result_format = result_format.clone();
58                                    move |default_ds| {
59                                        let mut sd = ServiceDescription::new(iri.clone());
60                                        sd.add_supported_language(&sl);
61                                        sd.add_feature(&feature);
62                                        sd.add_result_format(&result_format);
63                                        sd.add_default_dataset(&default_ds);
64                                        ok(&sd)
65                                    }
66                                })
67                            }
68                        })
69                    }
70                })
71            })
72        })
73    }
74
75    pub fn default_dataset() -> impl RDFNodeParse<RDF, Output = Dataset>
76    where
77        RDF: FocusRDF + 'static,
78    {
79        property_iri(&SD_DEFAULT_DATASET).then(move |iri| ok(&Dataset::new(&iri)))
80    }
81
82    pub fn endpoint() -> impl RDFNodeParse<RDF, Output = IriS>
83    where
84        RDF: FocusRDF + 'static,
85    {
86        property_iri(&SD_ENDPOINT)
87    }
88
89    pub fn feature() -> impl RDFNodeParse<RDF, Output = Vec<Feature>>
90    where
91        RDF: FocusRDF,
92    {
93        property_values_iri(&SD_FEATURE).flat_map(|ref iris| {
94            let features = get_features(iris)?;
95            Ok(features)
96        })
97    }
98
99    pub fn result_format() -> impl RDFNodeParse<RDF, Output = Vec<ResultFormat>>
100    where
101        RDF: FocusRDF,
102    {
103        property_values_iri(&SD_RESULT_FORMAT).flat_map(|ref iris| {
104            let result_format = get_result_formats(iris)?;
105            Ok(result_format)
106        })
107    }
108
109    pub fn supported_language() -> impl RDFNodeParse<RDF, Output = Vec<SupportedLanguage>>
110    where
111        RDF: FocusRDF,
112    {
113        property_values_iri(&SD_SUPPORTED_LANGUAGE).flat_map(|ref iris| {
114            let langs = get_supported_languages(iris)?;
115            Ok(langs)
116        })
117    }
118
119    fn sd_service() -> RDF::Term {
120        SD_SERVICE.clone().into()
121    }
122}
123
124fn get_supported_languages(iris: &Vec<IriS>) -> PResult<Vec<SupportedLanguage>> {
125    let mut res = Vec::new();
126    for i in iris {
127        let supported_language = supported_language(i)?;
128        res.push(supported_language)
129    }
130    Ok(res)
131}
132
133fn get_features(iris: &Vec<IriS>) -> PResult<Vec<Feature>> {
134    let mut res = Vec::new();
135    for i in iris {
136        let feature = feature(i)?;
137        res.push(feature)
138    }
139    Ok(res)
140}
141
142fn get_result_formats(iris: &Vec<IriS>) -> PResult<Vec<ResultFormat>> {
143    let mut res = Vec::new();
144    for i in iris {
145        let res_format = result_format(i)?;
146        res.push(res_format)
147    }
148    Ok(res)
149}
150
151fn supported_language(iri: &IriS) -> PResult<SupportedLanguage> {
152    match iri.as_str() {
153        SD_SPARQL10_QUERY_STR => Ok(SupportedLanguage::SPARQL10Query),
154        SD_SPARQL11_QUERY_STR => Ok(SupportedLanguage::SPARQL11Query),
155        SD_SPARQL11_UPDATE_STR => Ok(SupportedLanguage::SPARQL11Update),
156        _ => Err(srdf::RDFParseError::Custom {
157            msg: format!("Unexpected value for supported language: {iri}"),
158        }),
159    }
160}
161
162fn result_format(iri: &IriS) -> PResult<ResultFormat> {
163    let rf = match iri.as_str() {
164        "http://www.w3.org/ns/formats/SPARQL_Results_XML" => ResultFormat::XML,
165        "http://www.w3.org/ns/formats/JSON-LD" => ResultFormat::JsonLD,
166        "http://www.w3.org/ns/formats/N-Triples" => ResultFormat::NTriples,
167        "http://www.w3.org/ns/formats/SPARQL_Results_CSV" => ResultFormat::CSV,
168        "http://www.w3.org/ns/formats/SPARQL_Results_JSON" => ResultFormat::JSON,
169        "http://www.w3.org/ns/formats/Turtle" => ResultFormat::Turtle,
170        "http://www.w3.org/ns/formats/SPARQL_Results_TSV" => ResultFormat::TSV,
171        "http://www.w3.org/ns/formats/RDF_XML" => ResultFormat::RdfXml,
172        _ => ResultFormat::Other(iri.clone()),
173    };
174    Ok(rf)
175}
176
177fn feature(iri: &IriS) -> PResult<Feature> {
178    match iri.as_str() {
179        SD_BASIC_FEDERATED_QUERY_STR => Ok(Feature::BasicFederatedQuery),
180        SD_UNION_DEFAULT_GRAPH_STR => Ok(Feature::UnionDefaultGraph),
181        SD_EMPTY_GRAPHS_STR => Ok(Feature::EmptyGraphs),
182        SD_REQUIRES_DATASET_STR => Ok(Feature::RequiresDataset),
183        SD_DEREFERENCES_URIS_STR => Ok(Feature::DereferencesURIs),
184        _ => Ok(Feature::Other(iri.clone())),
185    }
186}