shacl_validation/constraints/core/value/
class.rs1use crate::constraints::constraint_error::ConstraintError;
2use crate::constraints::NativeValidator;
3use crate::constraints::SparqlValidator;
4use crate::helpers::constraint::validate_ask_with;
5use crate::helpers::constraint::validate_with;
6use crate::helpers::srdf::get_objects_for;
7use crate::validation_report::result::ValidationResult;
8use crate::value_nodes::ValueNodeIteration;
9use crate::value_nodes::ValueNodes;
10use indoc::formatdoc;
11use shacl_ast::compiled::component::Class;
12use shacl_ast::compiled::component::CompiledComponent;
13use shacl_ast::compiled::shape::CompiledShape;
14use srdf::Query;
15use srdf::Sparql;
16use srdf::Term;
17use srdf::RDFS_SUBCLASS_OF;
18use srdf::RDF_TYPE;
19use std::fmt::Debug;
20
21impl<S: Query + 'static> NativeValidator<S> for Class<S> {
22 fn validate_native(
23 &self,
24 component: &CompiledComponent<S>,
25 shape: &CompiledShape<S>,
26 store: &S,
27 value_nodes: &ValueNodes<S>,
28 _source_shape: Option<&CompiledShape<S>>,
29 ) -> Result<Vec<ValidationResult>, ConstraintError> {
30 let class = |value_node: &S::Term| {
31 if value_node.is_literal() {
32 return true;
33 }
34
35 let is_class_valid = get_objects_for(store, value_node, &RDF_TYPE.clone().into())
36 .unwrap_or_default()
37 .iter()
38 .any(|ctype| {
39 ctype == self.class_rule()
40 || get_objects_for(store, ctype, &RDFS_SUBCLASS_OF.clone().into())
41 .unwrap_or_default()
42 .contains(self.class_rule())
43 });
44
45 !is_class_valid
46 };
47
48 validate_with(component, shape, value_nodes, ValueNodeIteration, class)
49 }
50}
51
52impl<S: Sparql + Debug + 'static> SparqlValidator<S> for Class<S> {
53 fn validate_sparql(
54 &self,
55 component: &CompiledComponent<S>,
56 shape: &CompiledShape<S>,
57 store: &S,
58 value_nodes: &ValueNodes<S>,
59 _source_shape: Option<&CompiledShape<S>>,
60 ) -> Result<Vec<ValidationResult>, ConstraintError> {
61 let class_value = self.class_rule().clone();
62
63 let query = move |value_node: &S::Term| {
64 formatdoc! {"
65 PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
66 PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
67 ASK {{ {} rdf:type/rdfs:subClassOf* {} }}
68 ", value_node, class_value,
69 }
70 };
71
72 validate_ask_with(component, shape, store, value_nodes, query)
73 }
74}