shex_ast/ast/
triple_expr.rs

1use std::{result, str::FromStr};
2
3use iri_s::{IriS, IriSError};
4use prefixmap::{Deref, DerefError, IriRef, PrefixMap};
5use serde::{Deserialize, Serialize, Serializer};
6
7use crate::ast::serde_string_or_struct::*;
8
9use super::{
10    annotation::Annotation, sem_act::SemAct, shape_expr::ShapeExpr,
11    triple_expr_label::TripleExprLabel,
12};
13
14#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
15#[serde(tag = "type")]
16pub enum TripleExpr {
17    EachOf {
18        #[serde(default, skip_serializing_if = "Option::is_none")]
19        id: Option<TripleExprLabel>,
20
21        expressions: Vec<TripleExprWrapper>,
22
23        #[serde(skip_serializing_if = "Option::is_none")]
24        min: Option<i32>,
25
26        #[serde(skip_serializing_if = "Option::is_none")]
27        max: Option<i32>,
28
29        #[serde(default, rename = "semActs", skip_serializing_if = "Option::is_none")]
30        sem_acts: Option<Vec<SemAct>>,
31
32        #[serde(default, skip_serializing_if = "Option::is_none")]
33        annotations: Option<Vec<Annotation>>,
34    },
35
36    OneOf {
37        #[serde(default, skip_serializing_if = "Option::is_none")]
38        id: Option<TripleExprLabel>,
39
40        expressions: Vec<TripleExprWrapper>,
41
42        #[serde(skip_serializing_if = "Option::is_none")]
43        min: Option<i32>,
44
45        #[serde(skip_serializing_if = "Option::is_none")]
46        max: Option<i32>,
47
48        #[serde(default, rename = "semActs", skip_serializing_if = "Option::is_none")]
49        sem_acts: Option<Vec<SemAct>>,
50
51        #[serde(default, skip_serializing_if = "Option::is_none")]
52        annotations: Option<Vec<Annotation>>,
53    },
54    TripleConstraint {
55        #[serde(default, skip_serializing_if = "Option::is_none")]
56        id: Option<TripleExprLabel>,
57
58        #[serde(default, skip_serializing_if = "Option::is_none")]
59        negated: Option<bool>,
60
61        #[serde(default, skip_serializing_if = "Option::is_none")]
62        inverse: Option<bool>,
63
64        predicate: IriRef,
65
66        #[serde(
67            default,
68            rename = "valueExpr",
69            skip_serializing_if = "Option::is_none",
70            serialize_with = "serialize_opt_box_string_or_struct",
71            deserialize_with = "deserialize_opt_box_string_or_struct"
72        )]
73        value_expr: Option<Box<ShapeExpr>>,
74
75        #[serde(skip_serializing_if = "Option::is_none")]
76        min: Option<i32>,
77
78        #[serde(skip_serializing_if = "Option::is_none")]
79        max: Option<i32>,
80
81        #[serde(default, rename = "semActs", skip_serializing_if = "Option::is_none")]
82        sem_acts: Option<Vec<SemAct>>,
83
84        #[serde(default, skip_serializing_if = "Option::is_none")]
85        annotations: Option<Vec<Annotation>>,
86    },
87
88    TripleExprRef(TripleExprLabel),
89}
90
91impl TripleExpr {
92    pub fn triple_constraint(
93        negated: Option<bool>,
94        inverse: Option<bool>,
95        predicate: IriRef,
96        se: Option<ShapeExpr>,
97        min: Option<i32>,
98        max: Option<i32>,
99    ) -> TripleExpr {
100        TripleExpr::TripleConstraint {
101            id: None,
102            negated,
103            inverse,
104            predicate,
105            value_expr: se.map(Box::new),
106            min,
107            max,
108            sem_acts: None,
109            annotations: None,
110        }
111    }
112
113    pub fn each_of(tes: Vec<TripleExpr>) -> TripleExpr {
114        let mut tews = Vec::new();
115        for te in tes {
116            tews.push(te.into())
117        }
118        TripleExpr::EachOf {
119            id: None,
120            expressions: tews,
121            min: None,
122            max: None,
123            sem_acts: None,
124            annotations: None,
125        }
126    }
127
128    pub fn one_of(tes: Vec<TripleExpr>) -> TripleExpr {
129        let mut tews = Vec::new();
130        for te in tes {
131            tews.push(te.into())
132        }
133        TripleExpr::OneOf {
134            id: None,
135            expressions: tews,
136            min: None,
137            max: None,
138            sem_acts: None,
139            annotations: None,
140        }
141    }
142
143    pub fn with_id(mut self, id: Option<TripleExprLabel>) -> Self {
144        self = match self {
145            TripleExpr::EachOf {
146                id: _,
147                expressions,
148                min,
149                max,
150                sem_acts,
151                annotations,
152            } => TripleExpr::EachOf {
153                id,
154                expressions,
155                min,
156                max,
157                sem_acts,
158                annotations,
159            },
160            TripleExpr::OneOf {
161                id: _,
162                expressions,
163                min,
164                max,
165                sem_acts,
166                annotations,
167            } => TripleExpr::OneOf {
168                id,
169                expressions,
170                min,
171                max,
172                sem_acts,
173                annotations,
174            },
175            TripleExpr::TripleConstraint {
176                id: _,
177                negated,
178                inverse,
179                predicate,
180                value_expr,
181                min,
182                max,
183                sem_acts,
184                annotations,
185            } => TripleExpr::TripleConstraint {
186                id,
187                negated,
188                inverse,
189                predicate,
190                value_expr,
191                min,
192                max,
193                sem_acts,
194                annotations,
195            },
196            TripleExpr::TripleExprRef(lbl) => {
197                panic!("Can't update id to TripleExprRef({lbl:?}")
198            }
199        };
200        self
201    }
202
203    pub fn with_min(mut self, new_min: Option<i32>) -> Self {
204        self = match self {
205            TripleExpr::EachOf {
206                id,
207                expressions,
208                min: _,
209                max,
210                sem_acts,
211                annotations,
212            } => TripleExpr::EachOf {
213                id,
214                expressions,
215                min: new_min,
216                max,
217                sem_acts,
218                annotations,
219            },
220            TripleExpr::OneOf {
221                id,
222                expressions,
223                min: _,
224                max,
225                sem_acts,
226                annotations,
227            } => TripleExpr::OneOf {
228                id,
229                expressions,
230                min: new_min,
231                max,
232                sem_acts,
233                annotations,
234            },
235            TripleExpr::TripleConstraint {
236                id,
237                negated,
238                inverse,
239                predicate,
240                value_expr,
241                min: _,
242                max,
243                sem_acts,
244                annotations,
245            } => TripleExpr::TripleConstraint {
246                id,
247                negated,
248                inverse,
249                predicate,
250                value_expr,
251                min: new_min,
252                max,
253                sem_acts,
254                annotations,
255            },
256            TripleExpr::TripleExprRef(lbl) => {
257                panic!("Can't update min to TripleExprRef({lbl:?}")
258            }
259        };
260        self
261    }
262
263    pub fn with_max(mut self, new_max: Option<i32>) -> Self {
264        self = match self {
265            TripleExpr::EachOf {
266                id,
267                expressions,
268                min,
269                max: _,
270                sem_acts,
271                annotations,
272            } => TripleExpr::EachOf {
273                id,
274                expressions,
275                min,
276                max: new_max,
277                sem_acts,
278                annotations,
279            },
280            TripleExpr::OneOf {
281                id,
282                expressions,
283                min,
284                max: _,
285                sem_acts,
286                annotations,
287            } => TripleExpr::OneOf {
288                id,
289                expressions,
290                min,
291                max: new_max,
292                sem_acts,
293                annotations,
294            },
295            TripleExpr::TripleConstraint {
296                id,
297                negated,
298                inverse,
299                predicate,
300                value_expr,
301                min,
302                max: _,
303                sem_acts,
304                annotations,
305            } => TripleExpr::TripleConstraint {
306                id,
307                negated,
308                inverse,
309                predicate,
310                value_expr,
311                min,
312                max: new_max,
313                sem_acts,
314                annotations,
315            },
316            TripleExpr::TripleExprRef(lbl) => {
317                panic!("Can't update max to TripleExprRef({lbl:?}")
318            }
319        };
320        self
321    }
322
323    pub fn with_sem_acts(mut self, new_sem_acts: Option<Vec<SemAct>>) -> Self {
324        self = match self {
325            TripleExpr::EachOf {
326                id,
327                expressions,
328                min,
329                max,
330                sem_acts: _,
331                annotations,
332            } => TripleExpr::EachOf {
333                id,
334                expressions,
335                min,
336                max,
337                sem_acts: new_sem_acts,
338                annotations,
339            },
340            TripleExpr::OneOf {
341                id,
342                expressions,
343                min,
344                max,
345                sem_acts: _,
346                annotations,
347            } => TripleExpr::OneOf {
348                id,
349                expressions,
350                min,
351                max,
352                sem_acts: new_sem_acts,
353                annotations,
354            },
355            TripleExpr::TripleConstraint {
356                id,
357                negated,
358                inverse,
359                predicate,
360                value_expr,
361                min,
362                max,
363                sem_acts: _,
364                annotations,
365            } => TripleExpr::TripleConstraint {
366                id,
367                negated,
368                inverse,
369                predicate,
370                value_expr,
371                min,
372                max,
373                sem_acts: new_sem_acts,
374                annotations,
375            },
376            TripleExpr::TripleExprRef(lbl) => {
377                panic!("Can't update sem_acts to TripleExprRef({lbl:?}")
378            }
379        };
380        self
381    }
382
383    pub fn with_annotations(mut self, new_annotations: Option<Vec<Annotation>>) -> Self {
384        self = match self {
385            TripleExpr::EachOf {
386                id,
387                expressions,
388                min,
389                max,
390                sem_acts,
391                annotations: _,
392            } => TripleExpr::EachOf {
393                id,
394                expressions,
395                min,
396                max,
397                sem_acts,
398                annotations: new_annotations,
399            },
400            TripleExpr::OneOf {
401                id,
402                expressions,
403                min,
404                max,
405                sem_acts,
406                annotations: new_annotations,
407            } => TripleExpr::OneOf {
408                id,
409                expressions,
410                min,
411                max,
412                sem_acts,
413                annotations: new_annotations,
414            },
415            TripleExpr::TripleConstraint {
416                id,
417                negated,
418                inverse,
419                predicate,
420                value_expr,
421                min,
422                max,
423                sem_acts,
424                annotations: _,
425            } => TripleExpr::TripleConstraint {
426                id,
427                negated,
428                inverse,
429                predicate,
430                value_expr,
431                min,
432                max,
433                sem_acts,
434                annotations: new_annotations,
435            },
436            TripleExpr::TripleExprRef(lbl) => {
437                panic!("Can't update annotations to TripleExprRef({lbl:?}")
438            }
439        };
440        self
441    }
442
443    pub fn add_annotation(&mut self, annotation: Annotation) {
444        match self {
445            Self::EachOf { annotations, .. } => {
446                if let Some(anns) = annotations {
447                    anns.push(annotation)
448                } else {
449                    *annotations = Some(vec![annotation])
450                }
451            }
452            Self::TripleConstraint { annotations, .. } => {
453                if let Some(anns) = annotations {
454                    anns.push(annotation)
455                } else {
456                    *annotations = Some(vec![annotation])
457                }
458            }
459            Self::OneOf { annotations, .. } => {
460                if let Some(anns) = annotations {
461                    anns.push(annotation)
462                } else {
463                    *annotations = Some(vec![annotation])
464                }
465            }
466            _ => todo!(),
467        }
468    }
469}
470
471impl Deref for TripleExpr {
472    fn deref(
473        &self,
474        base: &Option<IriS>,
475        prefixmap: &Option<PrefixMap>,
476    ) -> Result<Self, DerefError> {
477        match self {
478            TripleExpr::EachOf {
479                id,
480                expressions,
481                min,
482                max,
483                sem_acts,
484                annotations,
485            } => {
486                let id = <TripleExprLabel as Deref>::deref_opt(id, base, prefixmap)?;
487                let annotations =
488                    <Annotation as Deref>::deref_opt_vec(annotations, base, prefixmap)?;
489                let sem_acts = <SemAct as Deref>::deref_opt_vec(sem_acts, base, prefixmap)?;
490                let expressions =
491                    <TripleExprWrapper as Deref>::deref_vec(expressions, base, prefixmap)?;
492                Ok(TripleExpr::EachOf {
493                    id,
494                    expressions,
495                    min: *min,
496                    max: *max,
497                    sem_acts,
498                    annotations,
499                })
500            }
501            TripleExpr::OneOf {
502                id,
503                expressions,
504                min,
505                max,
506                sem_acts,
507                annotations,
508            } => {
509                let id = <TripleExprLabel as Deref>::deref_opt(id, base, prefixmap)?;
510                let annotations =
511                    <Annotation as Deref>::deref_opt_vec(annotations, base, prefixmap)?;
512                let sem_acts = <SemAct as Deref>::deref_opt_vec(sem_acts, base, prefixmap)?;
513                let expressions =
514                    <TripleExprWrapper as Deref>::deref_vec(expressions, base, prefixmap)?;
515                Ok(TripleExpr::OneOf {
516                    id,
517                    expressions,
518                    min: *min,
519                    max: *max,
520                    sem_acts,
521                    annotations,
522                })
523            }
524            TripleExpr::TripleConstraint {
525                id,
526                negated,
527                inverse,
528                predicate,
529                value_expr,
530                min,
531                max,
532                sem_acts,
533                annotations,
534            } => {
535                let id = <TripleExprLabel as Deref>::deref_opt(id, base, prefixmap)?;
536                let annotations =
537                    <Annotation as Deref>::deref_opt_vec(annotations, base, prefixmap)?;
538                let sem_acts = <SemAct as Deref>::deref_opt_vec(sem_acts, base, prefixmap)?;
539                let predicate = predicate.deref(base, prefixmap)?;
540                let value_expr = <ShapeExpr as Deref>::deref_opt_box(value_expr, base, prefixmap)?;
541                Ok(TripleExpr::TripleConstraint {
542                    id,
543                    negated: *negated,
544                    inverse: *inverse,
545                    predicate,
546                    value_expr,
547                    min: *min,
548                    max: *max,
549                    sem_acts,
550                    annotations,
551                })
552            }
553            TripleExpr::TripleExprRef(label) => {
554                let label = label.deref(base, prefixmap)?;
555                Ok(TripleExpr::TripleExprRef(label))
556            }
557        }
558    }
559}
560
561impl FromStr for TripleExpr {
562    type Err = IriSError;
563
564    fn from_str(s: &str) -> Result<Self, Self::Err> {
565        let iri_ref = IriRef::try_from(s)?;
566        Ok(TripleExpr::TripleExprRef(TripleExprLabel::IriRef {
567            value: iri_ref,
568        }))
569    }
570}
571
572impl SerializeStringOrStruct for TripleExpr {
573    fn serialize_string_or_struct<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
574    where
575        S: Serializer,
576    {
577        match &self {
578            TripleExpr::TripleExprRef(ref r) => r.serialize(serializer),
579            _ => self.serialize(serializer),
580        }
581    }
582}
583
584#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
585#[serde(transparent)]
586pub struct TripleExprWrapper {
587    #[serde(
588        serialize_with = "serialize_string_or_struct",
589        deserialize_with = "deserialize_string_or_struct"
590    )]
591    pub te: TripleExpr,
592}
593
594impl TripleExprWrapper {}
595
596impl Deref for TripleExprWrapper {
597    fn deref(
598        &self,
599        base: &Option<IriS>,
600        prefixmap: &Option<PrefixMap>,
601    ) -> Result<Self, DerefError> {
602        let te = self.te.deref(base, prefixmap)?;
603        Ok(TripleExprWrapper { te })
604    }
605}
606
607impl From<TripleExpr> for TripleExprWrapper {
608    fn from(value: TripleExpr) -> Self {
609        Self { te: value }
610    }
611}