1use shacl_ast::compiled::component::CompiledComponent;
2use shacl_ast::compiled::property_shape::CompiledPropertyShape;
3use shacl_ast::compiled::shape::CompiledShape;
4use srdf::matcher::Any;
5use srdf::Query;
6use srdf::SHACLPath;
7use srdf::Term;
8use srdf::Triple;
9use srdf::RDFS_SUBCLASS_OF;
10use srdf::RDF_TYPE;
11
12use super::Engine;
13use crate::constraints::NativeDeref;
14use crate::focus_nodes::FocusNodes;
15use crate::helpers::srdf::get_objects_for;
16use crate::helpers::srdf::get_subjects_for;
17use crate::validate_error::ValidateError;
18use crate::validation_report::result::ValidationResult;
19use crate::value_nodes::ValueNodes;
20use std::fmt::Debug;
21
22pub struct NativeEngine;
23
24impl<S: Query + Debug + 'static> Engine<S> for NativeEngine {
25 fn evaluate(
26 &self,
27 store: &S,
28 shape: &CompiledShape<S>,
29 component: &CompiledComponent<S>,
30 value_nodes: &ValueNodes<S>,
31 source_shape: Option<&CompiledShape<S>>,
32 ) -> Result<Vec<ValidationResult>, ValidateError> {
33 println!("NativeEngine, evaluate with shape {}", shape.id());
34 let validator = component.deref();
35 Ok(validator.validate_native(component, shape, store, value_nodes, source_shape)?)
36 }
37
38 fn target_node(&self, _: &S, node: &S::Term) -> Result<FocusNodes<S>, ValidateError> {
41 if node.is_blank_node() {
42 Err(ValidateError::TargetNodeBlankNode)
43 } else {
44 Ok(FocusNodes::new(std::iter::once(node.clone())))
45 }
46 }
47
48 fn target_class(&self, store: &S, class: &S::Term) -> Result<FocusNodes<S>, ValidateError> {
49 if !class.is_iri() {
50 return Err(ValidateError::TargetClassNotIri);
51 }
52
53 let rdf_type: S::IRI = RDF_TYPE.clone().into();
55
56 let focus_nodes = store
57 .triples_matching(Any, rdf_type, class.clone())
58 .map_err(|_| ValidateError::SRDF)?
59 .map(Triple::into_subject)
60 .map(Into::into);
61
62 Ok(FocusNodes::new(focus_nodes))
63 }
64
65 fn target_subject_of(
66 &self,
67 store: &S,
68 predicate: &S::IRI,
69 ) -> Result<FocusNodes<S>, ValidateError> {
70 let subjects = store
71 .triples_with_predicate(predicate.clone())
72 .map_err(|_| ValidateError::SRDF)?
73 .map(Triple::into_subject)
74 .map(Into::into);
75 let focus_nodes = FocusNodes::new(subjects);
76 Ok(focus_nodes)
77 }
78
79 fn target_object_of(
80 &self,
81 store: &S,
82 predicate: &S::IRI,
83 ) -> Result<FocusNodes<S>, ValidateError> {
84 let objects = store
85 .triples_with_predicate(predicate.clone())
86 .map_err(|_| ValidateError::SRDF)?
87 .map(Triple::into_object);
88 Ok(FocusNodes::new(objects))
89 }
90
91 fn implicit_target_class(
92 &self,
93 store: &S,
94 subject: &S::Term,
95 ) -> Result<FocusNodes<S>, ValidateError> {
96 let targets = get_subjects_for(store, &RDF_TYPE.clone().into(), subject)?;
97
98 let subclass_targets = get_subjects_for(store, &RDFS_SUBCLASS_OF.clone().into(), subject)?
99 .into_iter()
100 .flat_map(move |subclass| {
101 get_subjects_for(store, &RDF_TYPE.clone().into(), &subclass)
102 .into_iter()
103 .flatten()
104 });
105
106 Ok(FocusNodes::new(targets.into_iter().chain(subclass_targets)))
107 }
108
109 fn predicate(
110 &self,
111 store: &S,
112 _: &CompiledPropertyShape<S>,
113 predicate: &S::IRI,
114 focus_node: &S::Term,
115 ) -> Result<FocusNodes<S>, ValidateError> {
116 Ok(FocusNodes::new(
117 get_objects_for(store, focus_node, predicate)?.into_iter(),
118 ))
119 }
120
121 fn alternative(
122 &self,
123 _store: &S,
124 _shape: &CompiledPropertyShape<S>,
125 _paths: &[SHACLPath],
126 _focus_node: &S::Term,
127 ) -> Result<FocusNodes<S>, ValidateError> {
128 Err(ValidateError::NotImplemented {
129 msg: "alternative".to_string(),
130 })
131 }
132
133 fn sequence(
134 &self,
135 _store: &S,
136 _shape: &CompiledPropertyShape<S>,
137 _paths: &[SHACLPath],
138 _focus_node: &S::Term,
139 ) -> Result<FocusNodes<S>, ValidateError> {
140 Err(ValidateError::NotImplemented {
141 msg: "sequence".to_string(),
142 })
143 }
144
145 fn inverse(
146 &self,
147 _store: &S,
148 _shape: &CompiledPropertyShape<S>,
149 _path: &SHACLPath,
150 _focus_node: &S::Term,
151 ) -> Result<FocusNodes<S>, ValidateError> {
152 Err(ValidateError::NotImplemented {
153 msg: "inverse".to_string(),
154 })
155 }
156
157 fn zero_or_more(
158 &self,
159 _store: &S,
160 _shape: &CompiledPropertyShape<S>,
161 _path: &SHACLPath,
162 _focus_node: &S::Term,
163 ) -> Result<FocusNodes<S>, ValidateError> {
164 Err(ValidateError::NotImplemented {
165 msg: "zero_or_more".to_string(),
166 })
167 }
168
169 fn one_or_more(
170 &self,
171 _store: &S,
172 _shape: &CompiledPropertyShape<S>,
173 _path: &SHACLPath,
174 _focus_node: &S::Term,
175 ) -> Result<FocusNodes<S>, ValidateError> {
176 Err(ValidateError::NotImplemented {
177 msg: "one_or_more".to_string(),
178 })
179 }
180
181 fn zero_or_one(
182 &self,
183 _store: &S,
184 _shape: &CompiledPropertyShape<S>,
185 _path: &SHACLPath,
186 _focus_node: &S::Term,
187 ) -> Result<FocusNodes<S>, ValidateError> {
188 Err(ValidateError::NotImplemented {
189 msg: "zero_or_one".to_string(),
190 })
191 }
192}