shacl_ast/compiled/
component.rs

1use crate::component::Component;
2use crate::Schema;
3use crate::*;
4
5use super::compile_shape;
6use super::compile_shapes;
7use super::compiled_shacl_error::CompiledShaclError;
8use super::convert_iri_ref;
9use super::convert_value;
10use super::shape::CompiledShape;
11use iri_s::iri;
12use iri_s::IriS;
13use node_kind::NodeKind;
14use srdf::lang::Lang;
15use srdf::Rdf;
16
17#[derive(Debug)]
18pub enum CompiledComponent<S: Rdf> {
19    Class(Class<S>),
20    Datatype(Datatype<S>),
21    NodeKind(Nodekind),
22    MinCount(MinCount),
23    MaxCount(MaxCount),
24    MinExclusive(MinExclusive<S>),
25    MaxExclusive(MaxExclusive<S>),
26    MinInclusive(MinInclusive<S>),
27    MaxInclusive(MaxInclusive<S>),
28    MinLength(MinLength),
29    MaxLength(MaxLength),
30    Pattern(Pattern),
31    UniqueLang(UniqueLang),
32    LanguageIn(LanguageIn),
33    Equals(Equals<S>),
34    Disjoint(Disjoint<S>),
35    LessThan(LessThan<S>),
36    LessThanOrEquals(LessThanOrEquals<S>),
37    Or(Or<S>),
38    And(And<S>),
39    Not(Not<S>),
40    Xone(Xone<S>),
41    Closed(Closed<S>),
42    Node(Node<S>),
43    HasValue(HasValue<S>),
44    In(In<S>),
45    QualifiedValueShape(QualifiedValueShape<S>),
46}
47
48impl<S: Rdf> CompiledComponent<S> {
49    pub fn compile(component: Component, schema: &Schema) -> Result<Self, CompiledShaclError> {
50        let component = match component {
51            Component::Class(object) => {
52                let class_rule = object.into();
53                CompiledComponent::Class(Class::new(class_rule))
54            }
55            Component::Datatype(iri_ref) => {
56                let iri_ref = convert_iri_ref::<S>(iri_ref)?;
57                CompiledComponent::Datatype(Datatype::new(iri_ref))
58            }
59            Component::NodeKind(node_kind) => CompiledComponent::NodeKind(Nodekind::new(node_kind)),
60            Component::MinCount(count) => CompiledComponent::MinCount(MinCount::new(count)),
61            Component::MaxCount(count) => CompiledComponent::MaxCount(MaxCount::new(count)),
62            Component::MinExclusive(literal) => {
63                let literal: S::Literal = literal.clone().into();
64                let term = literal.into();
65                CompiledComponent::MinExclusive(MinExclusive::new(term))
66            }
67            Component::MaxExclusive(literal) => {
68                let literal: S::Literal = literal.clone().into();
69                let term = literal.into();
70                CompiledComponent::MaxExclusive(MaxExclusive::new(term))
71            }
72            Component::MinInclusive(literal) => {
73                let literal: S::Literal = literal.clone().into();
74                let term = literal.into();
75                CompiledComponent::MinInclusive(MinInclusive::new(term))
76            }
77            Component::MaxInclusive(literal) => {
78                let literal: S::Literal = literal.clone().into();
79                let term = literal.into();
80                CompiledComponent::MaxInclusive(MaxInclusive::new(term))
81            }
82            Component::MinLength(length) => CompiledComponent::MinLength(MinLength::new(length)),
83            Component::MaxLength(length) => CompiledComponent::MaxLength(MaxLength::new(length)),
84            Component::Pattern { pattern, flags } => {
85                CompiledComponent::Pattern(Pattern::new(pattern, flags))
86            }
87            Component::UniqueLang(lang) => CompiledComponent::UniqueLang(UniqueLang::new(lang)),
88            Component::LanguageIn { langs } => {
89                CompiledComponent::LanguageIn(LanguageIn::new(langs))
90            }
91            Component::Equals(iri_ref) => {
92                let iri_ref = convert_iri_ref::<S>(iri_ref)?;
93                CompiledComponent::Equals(Equals::new(iri_ref))
94            }
95            Component::Disjoint(iri_ref) => {
96                let iri_ref = convert_iri_ref::<S>(iri_ref)?;
97                CompiledComponent::Disjoint(Disjoint::new(iri_ref))
98            }
99            Component::LessThan(iri_ref) => {
100                let iri_ref = convert_iri_ref::<S>(iri_ref)?;
101                CompiledComponent::LessThan(LessThan::new(iri_ref))
102            }
103            Component::LessThanOrEquals(iri_ref) => {
104                let iri_ref = convert_iri_ref::<S>(iri_ref)?;
105                CompiledComponent::LessThanOrEquals(LessThanOrEquals::new(iri_ref))
106            }
107            Component::Or { shapes } => {
108                CompiledComponent::Or(Or::new(compile_shapes::<S>(shapes, schema)?))
109            }
110            Component::And { shapes } => {
111                CompiledComponent::And(And::new(compile_shapes::<S>(shapes, schema)?))
112            }
113            Component::Not { shape } => {
114                let shape = compile_shape::<S>(shape, schema)?;
115                CompiledComponent::Not(Not::new(shape))
116            }
117            Component::Xone { shapes } => {
118                CompiledComponent::Xone(Xone::new(compile_shapes::<S>(shapes, schema)?))
119            }
120            Component::Closed {
121                is_closed,
122                ignored_properties,
123            } => {
124                let properties = ignored_properties
125                    .into_iter()
126                    .map(|prop| convert_iri_ref::<S>(prop))
127                    .collect::<Result<Vec<_>, _>>()?;
128                CompiledComponent::Closed(Closed::new(is_closed, properties))
129            }
130            Component::Node { shape } => {
131                let shape = compile_shape::<S>(shape, schema)?;
132                CompiledComponent::Node(Node::new(shape))
133            }
134            Component::HasValue { value } => {
135                let term = convert_value::<S>(value)?;
136                CompiledComponent::HasValue(HasValue::new(term))
137            }
138            Component::In { values } => {
139                let terms = values
140                    .into_iter()
141                    .map(|value| convert_value::<S>(value))
142                    .collect::<Result<Vec<_>, _>>()?;
143                CompiledComponent::In(In::new(terms))
144            }
145            Component::QualifiedValueShape {
146                shape,
147                qualified_min_count,
148                qualified_max_count,
149                qualified_value_shapes_disjoint,
150            } => {
151                let shape = compile_shape::<S>(shape, schema)?;
152                CompiledComponent::QualifiedValueShape(QualifiedValueShape::new(
153                    shape,
154                    qualified_min_count,
155                    qualified_max_count,
156                    qualified_value_shapes_disjoint,
157                ))
158            }
159        };
160
161        Ok(component)
162    }
163}
164
165/// sh:maxCount specifies the maximum number of value nodes that satisfy the
166/// condition.
167///
168/// - IRI: https://www.w3.org/TR/shacl/#MaxCountConstraintComponent
169/// - DEF: If the number of value nodes is greater than $maxCount, there is a
170///   validation result.
171#[derive(Debug)]
172pub struct MaxCount {
173    max_count: usize,
174}
175
176impl MaxCount {
177    pub fn new(max_count: isize) -> Self {
178        MaxCount {
179            max_count: max_count as usize,
180        }
181    }
182
183    pub fn max_count(&self) -> usize {
184        self.max_count
185    }
186}
187
188/// sh:minCount specifies the minimum number of value nodes that satisfy the
189/// condition. If the minimum cardinality value is 0 then this constraint is
190/// always satisfied and so may be omitted.
191///
192/// - IRI: https://www.w3.org/TR/shacl/#MinCountConstraintComponent
193/// - DEF: If the number of value nodes is less than $minCount, there is a
194///   validation result.
195#[derive(Debug)]
196pub struct MinCount {
197    min_count: usize,
198}
199
200impl MinCount {
201    pub fn new(min_count: isize) -> Self {
202        MinCount {
203            min_count: min_count as usize,
204        }
205    }
206
207    pub fn min_count(&self) -> usize {
208        self.min_count
209    }
210}
211
212/// sh:and specifies the condition that each value node conforms to all provided
213/// shapes. This is comparable to conjunction and the logical "and" operator.
214///
215/// https://www.w3.org/TR/shacl/#AndConstraintComponent
216#[derive(Debug)]
217pub struct And<S: Rdf> {
218    shapes: Vec<CompiledShape<S>>,
219}
220
221impl<S: Rdf> And<S> {
222    pub fn new(shapes: Vec<CompiledShape<S>>) -> Self {
223        And { shapes }
224    }
225
226    pub fn shapes(&self) -> &Vec<CompiledShape<S>> {
227        &self.shapes
228    }
229}
230
231/// sh:not specifies the condition that each value node cannot conform to a
232/// given shape. This is comparable to negation and the logical "not" operator.
233///
234/// https://www.w3.org/TR/shacl/#NotConstraintComponent
235#[derive(Debug)]
236pub struct Not<S: Rdf> {
237    shape: CompiledShape<S>,
238}
239
240impl<S: Rdf> Not<S> {
241    pub fn new(shape: CompiledShape<S>) -> Self {
242        Not { shape }
243    }
244
245    pub fn shape(&self) -> &CompiledShape<S> {
246        &self.shape
247    }
248}
249
250/// sh:or specifies the condition that each value node conforms to at least one
251/// of the provided shapes. This is comparable to disjunction and the logical
252/// "or" operator.
253///
254/// https://www.w3.org/TR/shacl/#AndConstraintComponent
255
256#[derive(Debug)]
257pub struct Or<S: Rdf> {
258    shapes: Vec<CompiledShape<S>>,
259}
260
261impl<S: Rdf> Or<S> {
262    pub fn new(shapes: Vec<CompiledShape<S>>) -> Self {
263        Or { shapes }
264    }
265
266    pub fn shapes(&self) -> &Vec<CompiledShape<S>> {
267        &self.shapes
268    }
269}
270
271/// sh:or specifies the condition that each value node conforms to at least one
272/// of the provided shapes. This is comparable to disjunction and the logical
273/// "or" operator.
274///
275/// https://www.w3.org/TR/shacl/#XoneConstraintComponent
276#[derive(Debug)]
277pub struct Xone<S: Rdf> {
278    shapes: Vec<CompiledShape<S>>,
279}
280
281impl<S: Rdf> Xone<S> {
282    pub fn new(shapes: Vec<CompiledShape<S>>) -> Self {
283        Xone { shapes }
284    }
285
286    pub fn shapes(&self) -> &Vec<CompiledShape<S>> {
287        &self.shapes
288    }
289}
290
291/// Closed Constraint Component.
292///
293/// The RDF data model offers a huge amount of flexibility. Any node can in
294/// principle have values for any property. However, in some cases it makes
295/// sense to specify conditions on which properties can be applied to nodes.
296/// The SHACL Core language includes a property called sh:closed that can be
297/// used to specify the condition that each value node has values only for
298/// those properties that have been explicitly enumerated via the property
299/// shapes specified for the shape via sh:property.
300///
301/// https://www.w3.org/TR/shacl/#ClosedConstraintComponent
302#[derive(Debug)]
303pub struct Closed<S: Rdf> {
304    is_closed: bool,
305    ignored_properties: Vec<S::IRI>,
306}
307
308impl<S: Rdf> Closed<S> {
309    pub fn new(is_closed: bool, ignored_properties: Vec<S::IRI>) -> Self {
310        Closed {
311            is_closed,
312            ignored_properties,
313        }
314    }
315
316    pub fn is_closed(&self) -> bool {
317        self.is_closed
318    }
319
320    pub fn ignored_properties(&self) -> &Vec<S::IRI> {
321        &self.ignored_properties
322    }
323}
324
325/// sh:hasValue specifies the condition that at least one value node is equal to
326///  the given RDF term.
327///
328/// https://www.w3.org/TR/shacl/#HasValueConstraintComponent
329#[derive(Debug)]
330pub struct HasValue<S: Rdf> {
331    value: S::Term,
332}
333
334impl<S: Rdf> HasValue<S> {
335    pub fn new(value: S::Term) -> Self {
336        HasValue { value }
337    }
338
339    pub fn value(&self) -> &S::Term {
340        &self.value
341    }
342}
343
344/// sh:in specifies the condition that each value node is a member of a provided
345/// SHACL list.
346///
347/// https://www.w3.org/TR/shacl/#InConstraintComponent
348#[derive(Debug)]
349pub struct In<S: Rdf> {
350    values: Vec<S::Term>,
351}
352
353impl<S: Rdf> In<S> {
354    pub fn new(values: Vec<S::Term>) -> Self {
355        In { values }
356    }
357
358    pub fn values(&self) -> &Vec<S::Term> {
359        &self.values
360    }
361}
362
363/// sh:disjoint specifies the condition that the set of value nodes is disjoint
364/// with the set of objects of the triples that have the focus node as subject
365/// and the value of sh:disjoint as predicate.
366///
367/// https://www.w3.org/TR/shacl/#DisjointConstraintComponent
368#[derive(Debug)]
369pub struct Disjoint<S: Rdf> {
370    iri_ref: S::IRI,
371}
372
373impl<S: Rdf> Disjoint<S> {
374    pub fn new(iri_ref: S::IRI) -> Self {
375        Disjoint { iri_ref }
376    }
377
378    pub fn iri_ref(&self) -> &S::IRI {
379        &self.iri_ref
380    }
381}
382
383/// sh:equals specifies the condition that the set of all value nodes is equal
384/// to the set of objects of the triples that have the focus node as subject and
385/// the value of sh:equals as predicate.
386///
387/// https://www.w3.org/TR/shacl/#EqualsConstraintComponent
388#[derive(Debug)]
389pub struct Equals<S: Rdf> {
390    iri_ref: S::IRI,
391}
392
393impl<S: Rdf> Equals<S> {
394    pub fn new(iri_ref: S::IRI) -> Self {
395        Equals { iri_ref }
396    }
397
398    pub fn iri_ref(&self) -> &S::IRI {
399        &self.iri_ref
400    }
401}
402
403/// LessThanOrEquals Constraint Component.
404///
405/// sh:lessThanOrEquals specifies the condition that each value node is smaller
406/// than or equal to all the objects of the triples that have the focus node
407/// as subject and the value of sh:lessThanOrEquals as predicate.
408///
409/// https://www.w3.org/TR/shacl/#LessThanOrEqualsConstraintComponent
410#[derive(Debug)]
411pub struct LessThanOrEquals<S: Rdf> {
412    iri_ref: S::IRI,
413}
414
415impl<S: Rdf> LessThanOrEquals<S> {
416    pub fn new(iri_ref: S::IRI) -> Self {
417        LessThanOrEquals { iri_ref }
418    }
419
420    pub fn iri_ref(&self) -> &S::IRI {
421        &self.iri_ref
422    }
423}
424
425/// sh:lessThan specifies the condition that each value node is smaller than all
426/// the objects of the triples that have the focus node as subject and the
427/// value of sh:lessThan as predicate.
428///
429/// https://www.w3.org/TR/shacl/#LessThanConstraintComponent
430#[derive(Debug)]
431pub struct LessThan<S: Rdf> {
432    iri_ref: S::IRI,
433}
434
435impl<S: Rdf> LessThan<S> {
436    pub fn new(iri_ref: S::IRI) -> Self {
437        LessThan { iri_ref }
438    }
439
440    pub fn iri_ref(&self) -> &S::IRI {
441        &self.iri_ref
442    }
443}
444
445/// sh:node specifies the condition that each value node conforms to the given
446/// node shape.
447///
448/// https://www.w3.org/TR/shacl/#NodeShapeComponent
449#[derive(Debug)]
450pub struct Node<S: Rdf> {
451    shape: CompiledShape<S>,
452}
453
454impl<S: Rdf> Node<S> {
455    pub fn new(shape: CompiledShape<S>) -> Self {
456        Node { shape }
457    }
458
459    pub fn shape(&self) -> &CompiledShape<S> {
460        &self.shape
461    }
462}
463
464/// QualifiedValueShape Constraint Component.
465///
466/// sh:qualifiedValueShape specifies the condition that a specified number of
467///  value nodes conforms to the given shape. Each sh:qualifiedValueShape can
468///  have: one value for sh:qualifiedMinCount, one value for
469///  sh:qualifiedMaxCount or, one value for each, at the same subject.
470///
471/// https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent
472#[derive(Debug)]
473pub struct QualifiedValueShape<S: Rdf> {
474    shape: CompiledShape<S>,
475    qualified_min_count: Option<isize>,
476    qualified_max_count: Option<isize>,
477    qualified_value_shapes_disjoint: Option<bool>,
478}
479
480impl<S: Rdf> QualifiedValueShape<S> {
481    pub fn new(
482        shape: CompiledShape<S>,
483        qualified_min_count: Option<isize>,
484        qualified_max_count: Option<isize>,
485        qualified_value_shapes_disjoint: Option<bool>,
486    ) -> Self {
487        QualifiedValueShape {
488            shape,
489            qualified_min_count,
490            qualified_max_count,
491            qualified_value_shapes_disjoint,
492        }
493    }
494
495    pub fn shape(&self) -> &CompiledShape<S> {
496        &self.shape
497    }
498
499    pub fn qualified_min_count(&self) -> Option<isize> {
500        self.qualified_min_count
501    }
502
503    pub fn qualified_max_count(&self) -> Option<isize> {
504        self.qualified_max_count
505    }
506
507    pub fn qualified_value_shapes_disjoint(&self) -> Option<bool> {
508        self.qualified_value_shapes_disjoint
509    }
510}
511
512/// The condition specified by sh:languageIn is that the allowed language tags
513/// for each value node are limited by a given list of language tags.
514///
515/// https://www.w3.org/TR/shacl/#LanguageInConstraintComponent
516#[derive(Debug)]
517pub struct LanguageIn {
518    langs: Vec<Lang>,
519}
520
521impl LanguageIn {
522    pub fn new(langs: Vec<Lang>) -> Self {
523        LanguageIn { langs }
524    }
525
526    pub fn langs(&self) -> &Vec<Lang> {
527        &self.langs
528    }
529}
530
531/// sh:maxLength specifies the maximum string length of each value node that
532/// satisfies the condition. This can be applied to any literals and IRIs, but
533/// not to blank nodes.
534///
535/// https://www.w3.org/TR/shacl/#MaxLengthConstraintComponent
536#[derive(Debug)]
537pub struct MaxLength {
538    max_length: isize,
539}
540
541impl MaxLength {
542    pub fn new(max_length: isize) -> Self {
543        MaxLength { max_length }
544    }
545
546    pub fn max_length(&self) -> isize {
547        self.max_length
548    }
549}
550
551/// sh:minLength specifies the minimum string length of each value node that
552/// satisfies the condition. This can be applied to any literals and IRIs, but
553/// not to blank nodes.
554///
555/// https://www.w3.org/TR/shacl/#MinLengthConstraintComponent
556#[derive(Debug)]
557pub struct MinLength {
558    min_length: isize,
559}
560
561impl MinLength {
562    pub fn new(min_length: isize) -> Self {
563        MinLength { min_length }
564    }
565
566    pub fn min_length(&self) -> isize {
567        self.min_length
568    }
569}
570
571/// sh:property can be used to specify that each value node has a given property
572/// shape.
573///
574/// https://www.w3.org/TR/shacl/#PropertyShapeComponent
575#[derive(Debug)]
576pub struct Pattern {
577    pattern: String,
578    flags: Option<String>,
579}
580
581impl Pattern {
582    pub fn new(pattern: String, flags: Option<String>) -> Self {
583        Pattern { pattern, flags }
584    }
585
586    pub fn pattern(&self) -> &String {
587        &self.pattern
588    }
589
590    pub fn flags(&self) -> &Option<String> {
591        &self.flags
592    }
593}
594
595/// The property sh:uniqueLang can be set to true to specify that no pair of
596///  value nodes may use the same language tag.
597///
598/// https://www.w3.org/TR/shacl/#UniqueLangConstraintComponent
599#[derive(Debug)]
600pub struct UniqueLang {
601    unique_lang: bool,
602}
603
604impl UniqueLang {
605    pub fn new(unique_lang: bool) -> Self {
606        UniqueLang { unique_lang }
607    }
608
609    pub fn unique_lang(&self) -> bool {
610        self.unique_lang
611    }
612}
613
614/// The condition specified by sh:class is that each value node is a SHACL
615/// instance of a given type.
616///
617/// https://www.w3.org/TR/shacl/#ClassConstraintComponent
618#[derive(Debug)]
619pub struct Class<S: Rdf> {
620    class_rule: S::Term,
621}
622
623impl<S: Rdf> Class<S> {
624    pub fn new(class_rule: S::Term) -> Self {
625        Class { class_rule }
626    }
627
628    pub fn class_rule(&self) -> &S::Term {
629        &self.class_rule
630    }
631}
632
633/// sh:datatype specifies a condition to be satisfied with regards to the
634/// datatype of each value node.
635///
636/// https://www.w3.org/TR/shacl/#ClassConstraintComponent
637#[derive(Debug)]
638pub struct Datatype<S: Rdf> {
639    datatype: S::IRI,
640}
641
642impl<S: Rdf> Datatype<S> {
643    pub fn new(datatype: S::IRI) -> Self {
644        Datatype { datatype }
645    }
646
647    pub fn datatype(&self) -> &S::IRI {
648        &self.datatype
649    }
650}
651
652/// sh:nodeKind specifies a condition to be satisfied by the RDF node kind of
653/// each value node.
654///
655/// https://www.w3.org/TR/shacl/#NodeKindConstraintComponent
656#[derive(Debug)]
657pub struct Nodekind {
658    node_kind: NodeKind,
659}
660
661impl Nodekind {
662    pub fn new(node_kind: NodeKind) -> Self {
663        Nodekind { node_kind }
664    }
665
666    pub fn node_kind(&self) -> &NodeKind {
667        &self.node_kind
668    }
669}
670
671/// https://www.w3.org/TR/shacl/#MaxExclusiveConstraintComponent
672#[derive(Debug)]
673pub struct MaxExclusive<S: Rdf> {
674    max_exclusive: S::Term,
675}
676
677impl<S: Rdf> MaxExclusive<S> {
678    pub fn new(literal: S::Term) -> Self {
679        MaxExclusive {
680            max_exclusive: literal,
681        }
682    }
683
684    pub fn max_exclusive(&self) -> &S::Term {
685        &self.max_exclusive
686    }
687}
688
689/// https://www.w3.org/TR/shacl/#MaxInclusiveConstraintComponent
690#[derive(Debug)]
691pub struct MaxInclusive<S: Rdf> {
692    max_inclusive: S::Term,
693}
694
695impl<S: Rdf> MaxInclusive<S> {
696    pub fn new(literal: S::Term) -> Self {
697        MaxInclusive {
698            max_inclusive: literal,
699        }
700    }
701
702    pub fn max_inclusive(&self) -> &S::Term {
703        &self.max_inclusive
704    }
705}
706
707/// https://www.w3.org/TR/shacl/#MinExclusiveConstraintComponent
708#[derive(Debug)]
709pub struct MinExclusive<S: Rdf> {
710    min_exclusive: S::Term,
711}
712
713impl<S: Rdf> MinExclusive<S> {
714    pub fn new(literal: S::Term) -> Self {
715        MinExclusive {
716            min_exclusive: literal,
717        }
718    }
719
720    pub fn min_exclusive(&self) -> &S::Term {
721        &self.min_exclusive
722    }
723}
724
725/// https://www.w3.org/TR/shacl/#MinInclusiveConstraintComponent
726#[derive(Debug)]
727pub struct MinInclusive<S: Rdf> {
728    min_inclusive: S::Term,
729}
730
731impl<S: Rdf> MinInclusive<S> {
732    pub fn new(literal: S::Term) -> Self {
733        MinInclusive {
734            min_inclusive: literal,
735        }
736    }
737
738    pub fn min_inclusive(&self) -> &S::Term {
739        &self.min_inclusive
740    }
741}
742
743impl<S: Rdf> From<&CompiledComponent<S>> for IriS {
744    fn from(value: &CompiledComponent<S>) -> Self {
745        match value {
746            CompiledComponent::Class(_) => iri!(SH_CLASS_STR),
747            CompiledComponent::Datatype(_) => iri!(SH_DATATYPE_STR),
748            CompiledComponent::NodeKind(_) => iri!(SH_IRI_STR),
749            CompiledComponent::MinCount(_) => iri!(SH_MIN_COUNT_STR),
750            CompiledComponent::MaxCount(_) => iri!(SH_MAX_COUNT_STR),
751            CompiledComponent::MinExclusive(_) => iri!(SH_MIN_EXCLUSIVE_STR),
752            CompiledComponent::MaxExclusive(_) => iri!(SH_MAX_EXCLUSIVE_STR),
753            CompiledComponent::MinInclusive(_) => iri!(SH_MIN_INCLUSIVE_STR),
754            CompiledComponent::MaxInclusive(_) => iri!(SH_MAX_INCLUSIVE_STR),
755            CompiledComponent::MinLength(_) => iri!(SH_MIN_LENGTH_STR),
756            CompiledComponent::MaxLength(_) => iri!(SH_MAX_LENGTH_STR),
757            CompiledComponent::Pattern { .. } => iri!(SH_PATTERN_STR),
758            CompiledComponent::UniqueLang(_) => iri!(SH_UNIQUE_LANG_STR),
759            CompiledComponent::LanguageIn { .. } => iri!(SH_LANGUAGE_IN_STR),
760            CompiledComponent::Equals(_) => iri!(SH_EQUALS_STR),
761            CompiledComponent::Disjoint(_) => iri!(SH_DISJOINT_STR),
762            CompiledComponent::LessThan(_) => iri!(SH_LESS_THAN_STR),
763            CompiledComponent::LessThanOrEquals(_) => {
764                iri!(SH_LESS_THAN_OR_EQUALS_STR)
765            }
766            CompiledComponent::Or { .. } => iri!(SH_OR_STR),
767            CompiledComponent::And { .. } => iri!(SH_AND_STR),
768            CompiledComponent::Not { .. } => iri!(SH_NOT_STR),
769            CompiledComponent::Xone { .. } => iri!(SH_XONE_STR),
770            CompiledComponent::Closed { .. } => iri!(SH_CLOSED_STR),
771            CompiledComponent::Node { .. } => iri!(SH_NODE_STR),
772            CompiledComponent::HasValue { .. } => iri!(SH_HAS_VALUE_STR),
773            CompiledComponent::In { .. } => iri!(SH_IN_STR),
774            CompiledComponent::QualifiedValueShape { .. } => {
775                iri!(SH_QUALIFIED_VALUE_SHAPE_STR)
776            }
777        }
778    }
779}