1use std::{fmt::Display, io::BufRead, path::Path};
5
6use iri_s::IriS;
7use itertools::Itertools;
8use srdf::{RDFFormat, ReaderMode, SRDFGraph};
9
10use crate::{ServiceDescriptionError, ServiceDescriptionParser};
11
12#[derive(Clone, PartialEq, Eq, Default, Debug)]
13pub struct ServiceDescription {
14 endpoint: IriS,
15 default_dataset: Dataset,
16 supported_language: Vec<SupportedLanguage>,
17 feature: Vec<Feature>,
18 result_format: Vec<ResultFormat>,
19}
20
21#[derive(Clone, PartialEq, Eq, Default, Debug)]
22pub enum SupportedLanguage {
23 SPARQL10Query,
24
25 #[default]
26 SPARQL11Query,
27
28 SPARQL11Update,
29}
30
31impl Display for SupportedLanguage {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 SupportedLanguage::SPARQL10Query => write!(f, "SPARQL10Query"),
35 SupportedLanguage::SPARQL11Query => write!(f, "SPARQL11Query"),
36 SupportedLanguage::SPARQL11Update => write!(f, "SPARQL11Update"),
37 }
38 }
39}
40
41#[derive(Clone, PartialEq, Eq, Debug)]
42pub enum ResultFormat {
43 XML,
44 Turtle,
45 TSV,
46 RdfXml,
47 JSON,
48 NTriples,
49 CSV,
50 JsonLD,
51 Other(IriS),
52}
53
54impl Display for ResultFormat {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 match self {
57 ResultFormat::XML => write!(f, "XML"),
58 ResultFormat::Turtle => write!(f, "Turtle"),
59 ResultFormat::TSV => write!(f, "TSV"),
60 ResultFormat::RdfXml => write!(f, "RDF/XML"),
61 ResultFormat::JSON => write!(f, "JSON"),
62 ResultFormat::NTriples => write!(f, "N-TRIPLES"),
63 ResultFormat::CSV => write!(f, "CSV"),
64 ResultFormat::JsonLD => write!(f, "JSON_LD"),
65 ResultFormat::Other(iri) => write!(f, "ResultFormat({iri})",),
66 }
67 }
68}
69
70#[derive(Clone, PartialEq, Eq, Debug)]
72pub enum Feature {
73 DereferencesURIs,
74 UnionDefaultGraph,
75 RequiresDataset,
76 EmptyGraphs,
77 BasicFederatedQuery,
78 Other(IriS),
79}
80
81impl Display for Feature {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 match self {
84 Feature::DereferencesURIs => write!(f, "DereferencesURIs"),
85 Feature::UnionDefaultGraph => write!(f, "UnionDefaultGraph"),
86 Feature::RequiresDataset => write!(f, "RequiresDataset"),
87 Feature::EmptyGraphs => write!(f, "EmptyGraphs"),
88 Feature::BasicFederatedQuery => write!(f, "BasicFederatedQuery"),
89 Feature::Other(iri) => write!(f, "Feature({iri})"),
90 }
91 }
92}
93
94#[derive(Clone, PartialEq, Eq, Default, Debug)]
95pub struct Dataset {
96 term: IriS,
97 default_graph: GraphDescription,
98 named_graphs: Vec<NamedGraphDescription>,
99}
100
101impl Dataset {
102 pub fn new(iri: &IriS) -> Dataset {
103 Dataset {
104 term: iri.clone(),
105 default_graph: GraphDescription::default(),
106 named_graphs: Vec::new(),
107 }
108 }
109}
110
111impl Display for Dataset {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 writeln!(f, "Dataset: {}", self.term)
114 }
115}
116
117#[derive(Clone, PartialEq, Eq, Default, Debug)]
118pub struct GraphDescription {
119 triples: u128,
120 class_partition: Vec<ClassPartition>,
121}
122
123#[derive(Clone, PartialEq, Eq, Default, Debug)]
124pub struct NamedGraphDescription {}
125
126#[derive(Clone, PartialEq, Eq, Default, Debug)]
127pub struct ClassPartition {
128 class: IriS,
129 property_partition: PropertyPartition,
130}
131
132#[derive(Clone, PartialEq, Eq, Default, Debug)]
133pub struct PropertyPartition {
134 property: IriS,
135 class_partition: Vec<ClassPartition>,
136 datatype_partition: Option<DatatypePartition>,
137}
138
139#[derive(Clone, PartialEq, Eq, Default, Debug)]
140pub struct DatatypePartition {
141 datatype: IriS,
142}
143
144impl ServiceDescription {
145 pub fn new(endpoint: IriS) -> ServiceDescription {
146 ServiceDescription {
147 endpoint: endpoint.clone(),
148 default_dataset: Dataset::default(),
149 supported_language: Vec::new(),
150 feature: Vec::new(),
151 result_format: Vec::new(),
152 }
153 }
154
155 pub fn from_path<P: AsRef<Path>>(
156 path: P,
157 format: &RDFFormat,
158 base: Option<&str>,
159 reader_mode: &ReaderMode,
160 ) -> Result<ServiceDescription, ServiceDescriptionError> {
161 let rdf = SRDFGraph::from_path(path, format, base, reader_mode)?;
162 let mut parser = ServiceDescriptionParser::new(rdf);
163 let service = parser.parse()?;
164 Ok(service)
165 }
166
167 pub fn from_reader<R: BufRead>(
168 read: R,
169 format: &RDFFormat,
170 base: Option<&str>,
171 reader_mode: &ReaderMode,
172 ) -> Result<ServiceDescription, ServiceDescriptionError> {
173 let rdf = SRDFGraph::from_reader(read, format, base, reader_mode)?;
174 let mut parser = ServiceDescriptionParser::new(rdf);
175 let service = parser.parse()?;
176 Ok(service)
177 }
178
179 pub fn add_supported_language(&mut self, supported_language: &[SupportedLanguage]) {
180 supported_language.clone_into(&mut self.supported_language);
181 }
182
183 pub fn add_feature(&mut self, feature: &[Feature]) {
184 feature.clone_into(&mut self.feature);
185 }
186
187 pub fn add_result_format(&mut self, result_format: &[ResultFormat]) {
188 result_format.clone_into(&mut self.result_format);
189 }
190
191 pub fn add_default_dataset(&mut self, default_dataset: &Dataset) {
192 self.default_dataset = default_dataset.clone();
193 }
194}
195
196impl Display for ServiceDescription {
197 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198 writeln!(f, "Service")?;
199 writeln!(f, " endpoint: {}", self.endpoint.as_str())?;
200 let sup_lang = self
201 .supported_language
202 .iter()
203 .map(|l| l.to_string())
204 .join(", ");
205 writeln!(f, " supportedLanguage: [{sup_lang}]")?;
206 let feature = self.feature.iter().map(|l| l.to_string()).join(", ");
207 writeln!(f, " feature: [{feature}]")?;
208 let result = self.result_format.iter().map(|l| l.to_string()).join(", ");
209 writeln!(f, " result_format: [{result}]")?;
210 writeln!(f, " default_dataset: {}", self.default_dataset)?;
211 Ok(())
212 }
213}