shacl_validation/constraints/core/string_based/
unique_lang.rs1use std::cell::RefCell;
2use std::rc::Rc;
3
4use crate::constraints::constraint_error::ConstraintError;
5use crate::constraints::NativeValidator;
6use crate::constraints::SparqlValidator;
7use crate::constraints::Validator;
8use crate::engine::native::NativeEngine;
9use crate::engine::sparql::SparqlEngine;
10use crate::engine::Engine;
11use crate::helpers::constraint::validate_with;
12use crate::validation_report::result::ValidationResult;
13use crate::value_nodes::ValueNodeIteration;
14use crate::value_nodes::ValueNodes;
15use shacl_ast::compiled::component::CompiledComponent;
16use shacl_ast::compiled::component::UniqueLang;
17use shacl_ast::compiled::shape::CompiledShape;
18use srdf::Query;
19use srdf::Rdf;
20use srdf::Sparql;
21use std::fmt::Debug;
22
23impl<S: Rdf + Debug> Validator<S> for UniqueLang {
24 fn validate(
25 &self,
26 component: &CompiledComponent<S>,
27 shape: &CompiledShape<S>,
28 _: &S,
29 _: impl Engine<S>,
30 value_nodes: &ValueNodes<S>,
31 _source_shape: Option<&CompiledShape<S>>,
32 ) -> Result<Vec<ValidationResult>, ConstraintError> {
33 if !self.unique_lang() {
34 return Ok(Default::default());
35 }
36
37 let langs: Rc<RefCell<Vec<_>>> = Rc::new(RefCell::new(Vec::new()));
38
39 let unique_lang = |value_node: &S::Term| {
40 let tmp: Result<S::Literal, _> = value_node.clone().try_into();
41 if let Ok(lang) = tmp {
42 let lang = lang.clone();
43 let mut langs_borrowed = langs.borrow_mut();
44 match langs_borrowed.contains(&lang) {
45 true => return true,
46 false => langs_borrowed.push(lang),
47 }
48 }
49 false
50 };
51
52 validate_with(
53 component,
54 shape,
55 value_nodes,
56 ValueNodeIteration,
57 unique_lang,
58 )
59 }
60}
61
62impl<S: Query + Debug + 'static> NativeValidator<S> for UniqueLang {
63 fn validate_native(
64 &self,
65 component: &CompiledComponent<S>,
66 shape: &CompiledShape<S>,
67 store: &S,
68 value_nodes: &ValueNodes<S>,
69 source_shape: Option<&CompiledShape<S>>,
70 ) -> Result<Vec<ValidationResult>, ConstraintError> {
71 self.validate(
72 component,
73 shape,
74 store,
75 NativeEngine,
76 value_nodes,
77 source_shape,
78 )
79 }
80}
81
82impl<S: Sparql + Debug + 'static> SparqlValidator<S> for UniqueLang {
83 fn validate_sparql(
84 &self,
85 component: &CompiledComponent<S>,
86 shape: &CompiledShape<S>,
87 store: &S,
88 value_nodes: &ValueNodes<S>,
89 source_shape: Option<&CompiledShape<S>>,
90 ) -> Result<Vec<ValidationResult>, ConstraintError> {
91 self.validate(
92 component,
93 shape,
94 store,
95 SparqlEngine,
96 value_nodes,
97 source_shape,
98 )
99 }
100}