shacl_validation/helpers/
constraint.rs1use shacl_ast::compiled::component::CompiledComponent;
2use shacl_ast::compiled::shape::CompiledShape;
3use srdf::Object;
4use srdf::Rdf;
5use srdf::Sparql;
6
7use crate::constraints::constraint_error::ConstraintError;
8use crate::validation_report::result::ValidationResult;
9use crate::value_nodes::IterationStrategy;
10use crate::value_nodes::ValueNodeIteration;
11use crate::value_nodes::ValueNodes;
12
13fn apply<S: Rdf, I: IterationStrategy<S>>(
14 component: &CompiledComponent<S>,
15 shape: &CompiledShape<S>,
16 value_nodes: &ValueNodes<S>,
17 iteration_strategy: I,
18 evaluator: impl Fn(&I::Item) -> Result<bool, ConstraintError>,
19) -> Result<Vec<ValidationResult>, ConstraintError> {
20 let results = iteration_strategy
21 .iterate(value_nodes)
22 .flat_map(|(focus_node, item)| {
23 if let Ok(condition) = evaluator(item) {
24 if condition {
25 let focus = focus_node.clone().into();
26 let component = Object::iri(component.into());
27 let severity = shape.severity().clone().into();
28 let source = Some(shape.id().clone().into());
29 return Some(
30 ValidationResult::new(focus, component, severity).with_source(source),
31 );
32 }
33 }
34 None
35 })
36 .collect();
37
38 Ok(results)
39}
40
41pub fn validate_with<S: Rdf, I: IterationStrategy<S>>(
42 component: &CompiledComponent<S>,
43 shape: &CompiledShape<S>,
44 value_nodes: &ValueNodes<S>,
45 iteration_strategy: I,
46 evaluator: impl Fn(&I::Item) -> bool,
47) -> Result<Vec<ValidationResult>, ConstraintError> {
48 apply(
49 component,
50 shape,
51 value_nodes,
52 iteration_strategy,
53 |item: &I::Item| Ok(evaluator(item)),
54 )
55}
56
57pub fn validate_ask_with<S: Sparql>(
58 component: &CompiledComponent<S>,
59 shape: &CompiledShape<S>,
60 store: &S,
61 value_nodes: &ValueNodes<S>,
62 eval_query: impl Fn(&S::Term) -> String,
63) -> Result<Vec<ValidationResult>, ConstraintError> {
64 apply(
65 component,
66 shape,
67 value_nodes,
68 ValueNodeIteration,
69 |value_node| match store.query_ask(&eval_query(value_node)) {
70 Ok(ask) => Ok(!ask),
71 Err(err) => Err(ConstraintError::Query(format!("ASK query failed: {}", err))),
72 },
73 )
74}