shacl_validation/constraints/core/logical/
xone.rs1use shacl_ast::compiled::component::CompiledComponent;
2use shacl_ast::compiled::component::Xone;
3use shacl_ast::compiled::shape::CompiledShape;
4use srdf::Query;
5use srdf::Rdf;
6use srdf::Sparql;
7use std::fmt::Debug;
8
9use crate::constraints::constraint_error::ConstraintError;
10use crate::constraints::NativeValidator;
11use crate::constraints::SparqlValidator;
12use crate::constraints::Validator;
13use crate::engine::native::NativeEngine;
14use crate::engine::sparql::SparqlEngine;
15use crate::engine::Engine;
16use crate::focus_nodes::FocusNodes;
17use crate::helpers::constraint::validate_with;
18use crate::shape::Validate;
19use crate::validation_report::result::ValidationResult;
20use crate::value_nodes::ValueNodeIteration;
21use crate::value_nodes::ValueNodes;
22
23impl<S: Rdf + Debug> Validator<S> for Xone<S> {
24 fn validate(
25 &self,
26 component: &CompiledComponent<S>,
27 shape: &CompiledShape<S>,
28 store: &S,
29 engine: impl Engine<S>,
30 value_nodes: &ValueNodes<S>,
31 _source_shape: Option<&CompiledShape<S>>,
32 ) -> Result<Vec<ValidationResult>, ConstraintError> {
33 let xone = |value_node: &S::Term| {
34 self.shapes()
35 .iter()
36 .filter(|shape| {
37 let focus_nodes = FocusNodes::new(std::iter::once(value_node.clone()));
38 match shape.validate(store, &engine, Some(&focus_nodes), Some(shape)) {
39 Ok(results) => results.is_empty(),
40 Err(_) => false,
41 }
42 })
43 .count()
44 .ne(&1usize)
45 };
46
47 validate_with(component, shape, value_nodes, ValueNodeIteration, xone)
48 }
49}
50
51impl<S: Query + Debug + 'static> NativeValidator<S> for Xone<S> {
52 fn validate_native(
53 &self,
54 component: &CompiledComponent<S>,
55 shape: &CompiledShape<S>,
56 store: &S,
57 value_nodes: &ValueNodes<S>,
58 source_shape: Option<&CompiledShape<S>>,
59 ) -> Result<Vec<ValidationResult>, ConstraintError> {
60 self.validate(
61 component,
62 shape,
63 store,
64 NativeEngine,
65 value_nodes,
66 source_shape,
67 )
68 }
69}
70
71impl<S: Sparql + Debug + 'static> SparqlValidator<S> for Xone<S> {
72 fn validate_sparql(
73 &self,
74 component: &CompiledComponent<S>,
75 shape: &CompiledShape<S>,
76 store: &S,
77 value_nodes: &ValueNodes<S>,
78 source_shape: Option<&CompiledShape<S>>,
79 ) -> Result<Vec<ValidationResult>, ConstraintError> {
80 self.validate(
81 component,
82 shape,
83 store,
84 SparqlEngine,
85 value_nodes,
86 source_shape,
87 )
88 }
89}