shacl_validation/engine/
mod.rs

1use shacl_ast::compiled::component::CompiledComponent;
2use shacl_ast::compiled::property_shape::CompiledPropertyShape;
3use shacl_ast::compiled::shape::CompiledShape;
4use shacl_ast::compiled::target::CompiledTarget;
5use srdf::Rdf;
6use srdf::SHACLPath;
7
8use crate::focus_nodes::FocusNodes;
9use crate::validate_error::ValidateError;
10use crate::validation_report::result::ValidationResult;
11use crate::value_nodes::ValueNodes;
12
13pub mod native;
14pub mod sparql;
15
16pub trait Engine<S: Rdf> {
17    fn evaluate(
18        &self,
19        store: &S,
20        shape: &CompiledShape<S>,
21        component: &CompiledComponent<S>,
22        value_nodes: &ValueNodes<S>,
23        source_shape: Option<&CompiledShape<S>>,
24    ) -> Result<Vec<ValidationResult>, ValidateError>;
25
26    fn focus_nodes(
27        &self,
28        store: &S,
29        targets: &[CompiledTarget<S>],
30    ) -> Result<FocusNodes<S>, ValidateError> {
31        // TODO: here it would be nice to return an error...
32        let targets = targets
33            .iter()
34            .flat_map(|target| match target {
35                CompiledTarget::Node(node) => self.target_node(store, node),
36                CompiledTarget::Class(class) => self.target_class(store, class),
37                CompiledTarget::SubjectsOf(predicate) => self.target_subject_of(store, predicate),
38                CompiledTarget::ObjectsOf(predicate) => self.target_object_of(store, predicate),
39                CompiledTarget::ImplicitClass(class) => self.implicit_target_class(store, class),
40            })
41            .flatten();
42
43        Ok(FocusNodes::new(targets))
44    }
45
46    /// If s is a shape in a shapes graph SG and s has value t for sh:targetNode
47    /// in SG then { t } is a target from any data graph for s in SG.
48    fn target_node(&self, store: &S, node: &S::Term) -> Result<FocusNodes<S>, ValidateError>;
49
50    fn target_class(&self, store: &S, class: &S::Term) -> Result<FocusNodes<S>, ValidateError>;
51
52    fn target_subject_of(
53        &self,
54        store: &S,
55        predicate: &S::IRI,
56    ) -> Result<FocusNodes<S>, ValidateError>;
57
58    fn target_object_of(
59        &self,
60        store: &S,
61        predicate: &S::IRI,
62    ) -> Result<FocusNodes<S>, ValidateError>;
63
64    fn implicit_target_class(
65        &self,
66        store: &S,
67        shape: &S::Term,
68    ) -> Result<FocusNodes<S>, ValidateError>;
69
70    fn path(
71        &self,
72        store: &S,
73        shape: &CompiledPropertyShape<S>,
74        focus_node: &S::Term,
75    ) -> Result<FocusNodes<S>, ValidateError> {
76        match shape.path() {
77            SHACLPath::Predicate { pred } => {
78                self.predicate(store, shape, &pred.clone().into(), focus_node)
79            }
80            SHACLPath::Alternative { paths } => self.alternative(store, shape, paths, focus_node),
81            SHACLPath::Sequence { paths } => self.sequence(store, shape, paths, focus_node),
82            SHACLPath::Inverse { path } => self.inverse(store, shape, path, focus_node),
83            SHACLPath::ZeroOrMore { path } => self.zero_or_more(store, shape, path, focus_node),
84            SHACLPath::OneOrMore { path } => self.one_or_more(store, shape, path, focus_node),
85            SHACLPath::ZeroOrOne { path } => self.zero_or_one(store, shape, path, focus_node),
86        }
87    }
88
89    fn predicate(
90        &self,
91        store: &S,
92        shape: &CompiledPropertyShape<S>,
93        predicate: &S::IRI,
94        focus_node: &S::Term,
95    ) -> Result<FocusNodes<S>, ValidateError>;
96
97    fn alternative(
98        &self,
99        store: &S,
100        shape: &CompiledPropertyShape<S>,
101        paths: &[SHACLPath],
102        focus_node: &S::Term,
103    ) -> Result<FocusNodes<S>, ValidateError>;
104
105    fn sequence(
106        &self,
107        store: &S,
108        shape: &CompiledPropertyShape<S>,
109        paths: &[SHACLPath],
110        focus_node: &S::Term,
111    ) -> Result<FocusNodes<S>, ValidateError>;
112
113    fn inverse(
114        &self,
115        store: &S,
116        shape: &CompiledPropertyShape<S>,
117        path: &SHACLPath,
118        focus_node: &S::Term,
119    ) -> Result<FocusNodes<S>, ValidateError>;
120
121    fn zero_or_more(
122        &self,
123        store: &S,
124        shape: &CompiledPropertyShape<S>,
125        path: &SHACLPath,
126        focus_node: &S::Term,
127    ) -> Result<FocusNodes<S>, ValidateError>;
128
129    fn one_or_more(
130        &self,
131        store: &S,
132        shape: &CompiledPropertyShape<S>,
133        path: &SHACLPath,
134        focus_node: &S::Term,
135    ) -> Result<FocusNodes<S>, ValidateError>;
136
137    fn zero_or_one(
138        &self,
139        store: &S,
140        shape: &CompiledPropertyShape<S>,
141        path: &SHACLPath,
142        focus_node: &S::Term,
143    ) -> Result<FocusNodes<S>, ValidateError>;
144}