sparql_service/
service_description_parser.rs1use 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 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}