Skip to content

Commit bc95705

Browse files
authored
Merge pull request #262 from rudof-project/issue-246
Implementation of the Query trait
2 parents 8952b62 + a860319 commit bc95705

File tree

19 files changed

+670
-1162
lines changed

19 files changed

+670
-1162
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ members = [
2323

2424
exclude = ["shex_compact_winnow"]
2525

26-
default-members = ["rudof_cli", "shacl_validation"]
26+
default-members = ["rudof_cli", "shacl_validation", "srdf"]
2727

2828
[workspace.package]
2929
edition = "2021"

rudof_cli/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ where
11831183
ShowNodeMode::Outgoing | ShowNodeMode::Both => {
11841184
writeln!(writer, "Outgoing arcs")?;
11851185
let map = if predicates.is_empty() {
1186-
match rdf.outgoing_arcs(&subject) {
1186+
match rdf.outgoing_arcs(subject.clone()) {
11871187
Result::Ok(rs) => rs,
11881188
Err(e) => bail!("Error obtaining outgoing arcs of {subject}: {e}"),
11891189
}
@@ -1215,8 +1215,8 @@ where
12151215
match show_node_mode {
12161216
ShowNodeMode::Incoming | ShowNodeMode::Both => {
12171217
writeln!(writer, "Incoming arcs")?;
1218-
let object = subject.clone().into();
1219-
let map = match rdf.incoming_arcs(&object) {
1218+
let object: S::Term = subject.clone().into();
1219+
let map = match rdf.incoming_arcs(object.clone()) {
12201220
Result::Ok(m) => m,
12211221
Err(e) => bail!("Can't get outgoing arcs of node {subject}: {e}"),
12221222
};

shacl_ast/src/converter/rdf_to_shacl/shacl_parser.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use iri_s::IriS;
22
use prefixmap::{IriRef, PrefixMap};
33
use srdf::{
4-
combine_parsers, combine_vec, has_type, not, ok, optional, parse_nodes, property_bool,
5-
property_value, property_values, property_values_int, property_values_iri,
6-
property_values_non_empty, rdf_list, term, FocusRDF, Iri as _, Literal, Object, PResult,
7-
RDFNode, RDFNodeParse, RDFParseError, RDFParser, Rdf, SHACLPath, Term, Triple as _, RDF_TYPE,
4+
combine_parsers, combine_vec, has_type, matcher::Any, not, ok, optional, parse_nodes,
5+
property_bool, property_value, property_values, property_values_int, property_values_iri,
6+
property_values_non_empty, rdf_list, term, FocusRDF, Iri as _, Literal, PResult, RDFNode,
7+
RDFNodeParse, RDFParseError, RDFParser, Rdf, SHACLPath, Term, Triple, RDF_TYPE,
88
};
99
use std::collections::{HashMap, HashSet};
1010

@@ -72,13 +72,13 @@ where
7272

7373
fn shapes_candidates(&mut self) -> Result<Vec<RDFNode>> {
7474
// subjects with type `sh:NodeShape`
75-
let node_shape_instances = self
75+
let node_shape_instances: HashSet<_> = self
7676
.rdf_parser
7777
.rdf
78-
.subjects_with_predicate_object(&Self::rdf_type(), &Self::sh_node_shape())
79-
.map_err(|e| ShaclParserError::Custom {
80-
msg: format!("Error obtaining values with type sh:NodeShape: {e}"),
81-
})?;
78+
.triples_matching(Any, Self::rdf_type(), Self::sh_node_shape())
79+
.map_err(|e| ShaclParserError::Custom { msg: e.to_string() })?
80+
.map(Triple::into_subject)
81+
.collect();
8282

8383
// subjects with property `sh:property`
8484
let subjects_property = self.objects_with_predicate(Self::sh_property())?;
@@ -197,16 +197,13 @@ where
197197
}
198198

199199
fn objects_with_predicate(&self, pred: RDF::IRI) -> Result<HashSet<RDF::Subject>> {
200-
let triples = self
200+
let values_as_subjects = self
201201
.rdf_parser
202202
.rdf
203-
.triples_with_predicate(&pred)
204-
.map_err(|e| ShaclParserError::Custom {
205-
msg: format!("Error obtaining values with predicate sh:property: {e}"),
206-
})?;
207-
let values_as_subjects = triples
208-
.iter()
209-
.flat_map(Self::triple_object_as_subject)
203+
.triples_with_predicate(pred)
204+
.map_err(|e| ShaclParserError::Custom { msg: e.to_string() })?
205+
.map(Triple::into_object)
206+
.flat_map(TryInto::try_into)
210207
.collect();
211208
Ok(values_as_subjects)
212209
}
@@ -249,16 +246,6 @@ where
249246
SH_NODE.clone().into()
250247
}
251248

252-
fn triple_object_as_subject(triple: &RDF::Triple) -> Result<RDF::Subject> {
253-
let subj: RDF::Subject = triple
254-
.obj()
255-
.try_into()
256-
.map_err(|_| ShaclParserError::Custom {
257-
msg: format!("Expected triple object value to act as a subject: {triple}"),
258-
})?;
259-
Ok(subj)
260-
}
261-
262249
fn shape<'a>(state: &'a mut State) -> impl RDFNodeParse<RDF, Output = Shape> + 'a
263250
where
264251
RDF: FocusRDF + 'a,

shacl_validation/src/engine/native.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use shacl_ast::compiled::component::CompiledComponent;
22
use shacl_ast::compiled::property_shape::CompiledPropertyShape;
33
use shacl_ast::compiled::shape::CompiledShape;
4+
use srdf::matcher::Any;
45
use srdf::Query;
56
use srdf::SHACLPath;
67
use srdf::Term;
@@ -48,12 +49,13 @@ impl<S: Query + Debug + 'static> Engine<S> for NativeEngine {
4849
return Err(ValidateError::TargetClassNotIri);
4950
}
5051

51-
let subjects = match store.subjects_with_predicate_object(&RDF_TYPE.clone().into(), class) {
52-
Ok(subjects) => subjects,
53-
Err(_) => return Err(ValidateError::SRDF),
54-
};
52+
let rdf_type: S::IRI = RDF_TYPE.clone().into();
5553

56-
let focus_nodes = subjects.iter().map(|subject| subject.clone().into());
54+
let focus_nodes = store
55+
.triples_matching(Any, rdf_type, class.clone())
56+
.map_err(|_| ValidateError::SRDF)?
57+
.map(Triple::into_subject)
58+
.map(Into::into);
5759

5860
Ok(FocusNodes::new(focus_nodes))
5961
}
@@ -63,27 +65,25 @@ impl<S: Query + Debug + 'static> Engine<S> for NativeEngine {
6365
store: &S,
6466
predicate: &S::IRI,
6567
) -> Result<FocusNodes<S>, ValidateError> {
66-
let triples = match store.triples_with_predicate(predicate) {
67-
Ok(triples) => triples,
68-
Err(_) => return Err(ValidateError::SRDF),
69-
};
70-
71-
Ok(FocusNodes::new(
72-
triples.iter().map(|triple| triple.subj().into()),
73-
))
68+
let subjects = store
69+
.triples_with_predicate(predicate.clone())
70+
.map_err(|_| ValidateError::SRDF)?
71+
.map(Triple::into_subject)
72+
.map(Into::into);
73+
let focus_nodes = FocusNodes::new(subjects);
74+
Ok(focus_nodes)
7475
}
7576

7677
fn target_object_of(
7778
&self,
7879
store: &S,
7980
predicate: &S::IRI,
8081
) -> Result<FocusNodes<S>, ValidateError> {
81-
let triples = match store.triples_with_predicate(predicate) {
82-
Ok(triples) => triples,
83-
Err(_) => return Err(ValidateError::SRDF),
84-
};
85-
86-
Ok(FocusNodes::new(triples.iter().map(Triple::obj)))
82+
let objects = store
83+
.triples_with_predicate(predicate.clone())
84+
.map_err(|_| ValidateError::SRDF)?
85+
.map(Triple::into_object);
86+
Ok(FocusNodes::new(objects))
8787
}
8888

8989
fn implicit_target_class(
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashSet;
22

3-
use srdf::{Query, RDFNode};
3+
use srdf::{matcher::Any, Query, RDFNode, Triple};
44

55
use super::helper_error::SRDFError;
66

@@ -23,7 +23,7 @@ pub(crate) fn get_objects_for<S: Query>(
2323
subject: &S::Term,
2424
predicate: &S::IRI,
2525
) -> Result<HashSet<S::Term>, SRDFError> {
26-
let subject = match subject.clone().try_into() {
26+
let subject: S::Subject = match subject.clone().try_into() {
2727
Ok(subject) => subject,
2828
Err(_) => {
2929
return Err(SRDFError::SRDFTermAsSubject {
@@ -32,26 +32,29 @@ pub(crate) fn get_objects_for<S: Query>(
3232
}
3333
};
3434

35-
store
36-
.objects_for_subject_predicate(&subject, predicate)
37-
.map_err(|e| SRDFError::ObjectsWithSubjectPredicate {
38-
predicate: format!("{predicate}"),
39-
subject: format!("{subject}"),
40-
error: format!("{e}"),
41-
})
35+
let triples = store
36+
.triples_matching(subject, predicate.clone(), Any)
37+
.map_err(|e| SRDFError::Srdf {
38+
error: e.to_string(),
39+
})?
40+
.map(Triple::into_object)
41+
.collect();
42+
43+
Ok(triples)
4244
}
4345

4446
pub(crate) fn get_subjects_for<S: Query>(
4547
store: &S,
4648
predicate: &S::IRI,
4749
object: &S::Term,
4850
) -> Result<HashSet<S::Term>, SRDFError> {
49-
match store.subjects_with_predicate_object(predicate, object) {
50-
Ok(ans) => Ok(ans.into_iter().map(Into::into).collect()),
51-
Err(e) => Err(SRDFError::SubjectsWithPredicateObject {
52-
predicate: format!("{predicate}"),
53-
object: format!("{object}"),
54-
error: format!("{e}"),
55-
}),
56-
}
51+
let values = store
52+
.triples_matching(Any, predicate.clone(), object.clone())
53+
.map_err(|e| SRDFError::Srdf {
54+
error: e.to_string(),
55+
})?
56+
.map(Triple::into_subject)
57+
.map(Into::into)
58+
.collect();
59+
Ok(values)
5760
}

shacl_validation/tests/mod.rs

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ use shacl_validation::validation_report::report::ValidationReport;
2121
use shacl_validation::validation_report::validation_report_error::ReportError;
2222
use sparql_service::RdfData;
2323
use sparql_service::RdfDataError;
24+
use srdf::matcher::Any;
2425
use srdf::Query;
2526
use srdf::RDFFormat;
2627
use srdf::Rdf;
28+
use srdf::Triple;
2729
use thiserror::Error;
2830

2931
mod core;
@@ -83,37 +85,32 @@ impl Manifest {
8385
) -> Result<HashSet<OxTerm>, TestSuiteError> {
8486
let mut entry_terms = HashSet::new();
8587

88+
let mf_entries: NamedNode = shacl_validation_vocab::MF_ENTRIES.clone().into();
8689
let entry_subject = store
87-
.objects_for_subject_predicate(
88-
&subject,
89-
&shacl_validation_vocab::MF_ENTRIES.clone().into(),
90-
)?
91-
.into_iter()
90+
.triples_matching(subject, mf_entries, Any)?
91+
.map(Triple::into_object)
9292
.next();
9393

9494
if let Some(mut subject) = entry_subject {
9595
loop {
96+
let inner_subject: OxSubject = subject.clone().try_into().unwrap();
97+
let rdf_first: NamedNode = srdf::RDF_FIRST.clone().into();
9698
match store
97-
.objects_for_subject_predicate(
98-
&subject.clone().try_into().unwrap(),
99-
&srdf::RDF_FIRST.clone().into(),
100-
)?
101-
.into_iter()
99+
.triples_matching(inner_subject.clone(), rdf_first, Any)?
100+
.map(Triple::into_object)
102101
.next()
103102
{
104103
Some(terms) => entry_terms.insert(terms),
105104
None => break,
106105
};
107106

107+
let rdf_rest: NamedNode = srdf::RDF_REST.clone().into();
108108
subject = match store
109-
.objects_for_subject_predicate(
110-
&subject.clone().try_into().unwrap(),
111-
&srdf::RDF_REST.clone().into(),
112-
)?
113-
.into_iter()
109+
.triples_matching(inner_subject, rdf_rest, Any)?
110+
.map(Triple::into_object)
114111
.next()
115112
{
116-
Some(subject) => subject,
113+
Some(term) => term,
117114
None => break,
118115
};
119116
}
@@ -125,48 +122,41 @@ impl Manifest {
125122
fn collect_tests(&self) -> Result<Vec<ShaclTest<RdfData>>, TestSuiteError> {
126123
let mut entries = Vec::new();
127124
for entry in &self.entries {
128-
let entry = entry.clone().try_into()?;
125+
let entry: OxSubject = entry.clone().try_into()?;
129126

130-
let action = self
127+
let mf_action: NamedNode = shacl_validation_vocab::MF_ACTION.clone().into();
128+
let action: OxSubject = self
131129
.store
132-
.objects_for_subject_predicate(
133-
&entry,
134-
&shacl_validation_vocab::MF_ACTION.clone().into(),
135-
)?
136-
.into_iter()
130+
.triples_matching(entry.clone(), mf_action, Any)?
131+
.map(Triple::into_object)
137132
.next()
138-
.unwrap();
139-
let action = action.try_into()?;
133+
.unwrap()
134+
.try_into()?;
140135

136+
let mf_result: NamedNode = shacl_validation_vocab::MF_RESULT.clone().into();
141137
let results = self
142138
.store
143-
.objects_for_subject_predicate(
144-
&entry,
145-
&shacl_validation_vocab::MF_RESULT.clone().into(),
146-
)?
147-
.into_iter()
139+
.triples_matching(entry, mf_result, Any)?
140+
.map(Triple::into_object)
148141
.next()
149142
.unwrap();
150143

151144
let report = ValidationReport::parse(&self.store, results)?;
152145

146+
let sht_data_graph: NamedNode = shacl_validation_vocab::SHT_DATA_GRAPH.clone().into();
153147
let data_graph_iri = self
154148
.store
155-
.objects_for_subject_predicate(
156-
&action,
157-
&shacl_validation_vocab::SHT_DATA_GRAPH.clone().into(),
158-
)?
159-
.into_iter()
149+
.triples_matching(action.clone(), sht_data_graph, Any)?
150+
.map(Triple::into_object)
160151
.next()
161152
.unwrap();
162153

154+
let sht_shapes_graph: NamedNode =
155+
shacl_validation_vocab::SHT_SHAPES_GRAPH.clone().into();
163156
let shapes_graph_iri = self
164157
.store
165-
.objects_for_subject_predicate(
166-
&action,
167-
&shacl_validation_vocab::SHT_SHAPES_GRAPH.clone().into(),
168-
)?
169-
.into_iter()
158+
.triples_matching(action, sht_shapes_graph, Any)?
159+
.map(Triple::into_object)
170160
.next()
171161
.unwrap();
172162

shex_ast/src/shexr/shexr_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use iri_s::IriS;
2-
use srdf::{literal::Literal, RDFParseError};
2+
use srdf::RDFParseError;
33
use std::fmt::Display;
44
use thiserror::Error;
55

shex_ast/src/shexr/shexr_parser.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@ use crate::{
44
BNode, NodeConstraint, NodeKind, ObjectValue, Schema, Shape, ShapeDecl, ShapeExpr,
55
ShapeExprLabel, ValueSetValue,
66
};
7-
use iri_s::iri;
87
use iri_s::IriS;
98
use prefixmap::IriRef;
109
use srdf::rdf_parser;
1110
use srdf::srdf_parser::*;
12-
use srdf::BlankNode as _;
1311
use srdf::FocusRDF;
14-
use srdf::Iri as _;
1512
use srdf::RDFParseError;
16-
use srdf::Term;
1713
use srdf::{Object, RDFParser};
1814

1915
type Result<A> = std::result::Result<A, ShExRError>;

0 commit comments

Comments
 (0)