1use std::collections::HashMap;
2
3use crate::ir::annotation::Annotation;
4use crate::ir::object_value::ObjectValue;
5use crate::ir::schema_ir::SchemaIR;
6use crate::ir::sem_act::SemAct;
7use crate::ir::shape::Shape;
8use crate::ir::shape_expr::ShapeExpr;
9use crate::ir::shape_label::ShapeLabel;
10use crate::ir::value_set::ValueSet;
11use crate::ir::value_set_value::ValueSetValue;
12use crate::ShapeExprLabel;
13use crate::{ast, ast::Schema as SchemaJson, SchemaIRError, ShapeLabelIdx};
14use crate::{CResult, Cond, Node, Pred};
15use iri_s::IriS;
16use lazy_static::lazy_static;
17use prefixmap::IriRef;
18use rbe::{rbe::Rbe, Component, MatchCond, Max, Min, RbeTable};
19use rbe::{Cardinality, Pending, RbeError, SingleCond};
20use srdf::literal::Literal;
21use srdf::Object;
22use tracing::debug;
23
24use super::node_constraint::NodeConstraint;
25
26lazy_static! {
27 static ref XSD_STRING: IriRef = IriRef::Iri(IriS::new_unchecked(
28 "http://www.w3.org/2001/XMLSchema#string"
29 ));
30 static ref RDF_LANG_STRING: IriRef = IriRef::Iri(IriS::new_unchecked(
31 "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
32 ));
33}
34
35#[derive(Debug, Default)]
36pub struct AST2IR {
38 shape_decls_counter: usize,
39}
40
41impl AST2IR {
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn compile(
47 &mut self,
48 schema_json: &SchemaJson,
49 compiled_schema: &mut SchemaIR,
50 ) -> CResult<()> {
51 debug!("Compiling schema_json: {compiled_schema:?}");
52 compiled_schema.set_prefixmap(schema_json.prefixmap());
53 self.collect_shape_labels(schema_json, compiled_schema)?;
54 self.collect_shape_exprs(schema_json, compiled_schema)?;
55 Ok(())
56 }
57
58 pub fn collect_shape_labels(
59 &mut self,
60 schema_json: &SchemaJson,
61 compiled_schema: &mut SchemaIR,
62 ) -> CResult<()> {
63 match &schema_json.shapes() {
64 None => Ok(()),
65 Some(sds) => {
66 for sd in sds {
67 let label = self.shape_expr_label_to_shape_label(&sd.id)?;
68 compiled_schema.add_shape(label, ShapeExpr::Empty);
69 self.shape_decls_counter += 1;
70 }
71 Ok(())
72 }
73 }
74 }
75
76 pub fn collect_shape_exprs(
77 &mut self,
78 schema_json: &SchemaJson,
79 compiled_schema: &mut SchemaIR,
80 ) -> CResult<()> {
81 match &schema_json.shapes() {
82 None => Ok(()),
83 Some(sds) => {
84 for sd in sds {
85 let idx = self.get_shape_label_idx(&sd.id, compiled_schema)?;
86 let se = self.compile_shape_decl(sd, &idx, compiled_schema)?;
87 compiled_schema.replace_shape(&idx, se)
88 }
89 Ok(())
90 }
91 }
92 }
93
94 fn shape_expr_label_to_shape_label(&self, id: &ShapeExprLabel) -> CResult<ShapeLabel> {
95 match id {
96 ShapeExprLabel::IriRef { value } => {
97 let shape_label = iri_ref_2_shape_label(value)?;
98 Ok(shape_label)
99 }
100 ShapeExprLabel::BNode { value } => Ok(ShapeLabel::BNode(value.clone())),
101 ShapeExprLabel::Start => Ok(ShapeLabel::Start),
102 }
103 }
104
105 fn get_shape_label_idx(
106 &self,
107 id: &ShapeExprLabel,
108 compiled_schema: &mut SchemaIR,
109 ) -> CResult<ShapeLabelIdx> {
110 let label = self.shape_expr_label_to_shape_label(id)?;
111 compiled_schema.get_shape_label_idx(&label)
112 }
113
114 fn compile_shape_decl(
115 &self,
116 sd: &ast::ShapeDecl,
117 idx: &ShapeLabelIdx,
118 compiled_schema: &mut SchemaIR,
119 ) -> CResult<ShapeExpr> {
120 self.compile_shape_expr(&sd.shape_expr, idx, compiled_schema)
121 }
122
123 fn ref2idx(
124 &self,
125 sref: &ast::ShapeExprLabel,
126 compiled_schema: &mut SchemaIR,
127 ) -> CResult<ShapeLabelIdx> {
128 let idx = self.get_shape_label_idx(sref, compiled_schema)?;
129 Ok(idx)
130 }
131
132 fn compile_shape_expr(
133 &self,
134 se: &ast::ShapeExpr,
135 idx: &ShapeLabelIdx,
136 compiled_schema: &mut SchemaIR,
137 ) -> CResult<ShapeExpr> {
138 let result: ShapeExpr = match se {
139 ast::ShapeExpr::Ref(se_ref) => {
140 let new_idx = self.ref2idx(se_ref, compiled_schema)?;
141 let se: ShapeExpr = ShapeExpr::Ref { idx: new_idx };
142 Ok::<ShapeExpr, SchemaIRError>(se)
143 }
144 ast::ShapeExpr::ShapeOr { shape_exprs: ses } => {
145 let mut cnv = Vec::new();
146 for sew in ses {
147 let se = self.compile_shape_expr(&sew.se, idx, compiled_schema)?;
148 cnv.push(se);
149 }
150 let display = match compiled_schema.find_shape_idx(idx) {
151 None => "internal OR".to_string(),
152 Some((Some(label), _)) => compiled_schema.show_label(label),
153 Some((None, _)) => "internal OR with some se".to_string(),
154 };
155
156 Ok(ShapeExpr::ShapeOr {
157 exprs: cnv,
158 display,
159 })
160 }
161 ast::ShapeExpr::ShapeAnd { shape_exprs: ses } => {
162 let mut cnv = Vec::new();
163 for sew in ses {
164 let se = self.compile_shape_expr(&sew.se, idx, compiled_schema)?;
165 cnv.push(se);
166 }
167 let display = match compiled_schema.find_shape_idx(idx) {
168 None => "internal AND".to_string(),
169 Some((Some(label), _)) => compiled_schema.show_label(label),
170 Some((None, _)) => "internal AND with some se".to_string(),
171 };
172 Ok(ShapeExpr::ShapeAnd {
173 exprs: cnv,
174 display,
175 })
176 }
177 ast::ShapeExpr::ShapeNot { shape_expr: sew } => {
178 let se = self.compile_shape_expr(&sew.se, idx, compiled_schema)?;
179 let display = match compiled_schema.find_shape_idx(idx) {
180 None => "internal NOT".to_string(),
181 Some((Some(label), _)) => compiled_schema.show_label(label),
182 Some((None, _)) => "internal NOT with some shape expr".to_string(),
183 };
184 Ok(ShapeExpr::ShapeNot {
185 expr: Box::new(se),
186 display,
187 })
188 }
189 ast::ShapeExpr::Shape(shape) => {
190 let new_extra = self.cnv_extra(&shape.extra)?;
191 let rbe_table = match &shape.expression {
192 None => RbeTable::new(),
193 Some(tew) => {
194 let mut table = RbeTable::new();
195 let rbe = self.triple_expr2rbe(&tew.te, compiled_schema, &mut table)?;
196 table.with_rbe(rbe);
197 table
198 }
199 };
200 let preds = Self::get_preds_shape(shape);
201 let references = self.get_references_shape(shape, compiled_schema);
202
203 let display = match compiled_schema.find_shape_idx(idx) {
204 None => "internal".to_string(),
205 Some((Some(label), _)) => compiled_schema.show_label(label),
206 Some((None, _)) => "internal with shape expr:".to_string(),
207 };
208
209 let shape = Shape::new(
210 Self::cnv_closed(&shape.closed),
211 new_extra,
212 rbe_table,
213 Self::cnv_sem_acts(&shape.sem_acts),
214 Self::cnv_annotations(&shape.annotations),
215 preds,
216 references,
217 display,
218 );
219 Ok(ShapeExpr::Shape(shape))
220 }
221 ast::ShapeExpr::NodeConstraint(nc) => {
222 let cond = Self::cnv_node_constraint(
223 self,
224 &nc.node_kind(),
225 &nc.datatype(),
226 &nc.xs_facet(),
227 &nc.values(),
228 )?;
229 let display = match compiled_schema.find_shape_idx(idx) {
230 None => "internal NodeConstraint".to_string(),
231 Some((Some(label), _)) => compiled_schema.show_label(label),
232 Some((None, _)) => "internal NodeConstraint with some shape expr".to_string(),
233 };
234 let node_constraint = NodeConstraint::new(nc.clone(), cond, display);
235 Ok(ShapeExpr::NodeConstraint(node_constraint))
236 }
237 ast::ShapeExpr::External => Ok(ShapeExpr::External {}),
238 }?;
239 Ok(result)
242 }
243
244 fn cnv_node_constraint(
245 &self,
246 nk: &Option<ast::NodeKind>,
247 dt: &Option<IriRef>,
248 xs_facet: &Option<Vec<ast::XsFacet>>,
249 values: &Option<Vec<ast::ValueSetValue>>,
250 ) -> CResult<Cond> {
251 let maybe_value_set = match values {
252 Some(vs) => {
253 let value_set = create_value_set(vs)?;
254 Some(value_set)
255 }
256 None => None,
257 };
258 node_constraint2match_cond(nk, dt, xs_facet, &maybe_value_set)
259 }
260
261 fn cnv_closed(closed: &Option<bool>) -> bool {
262 match closed {
263 None => false,
264 Some(closed) => *closed,
265 }
266 }
267
268 fn cnv_extra(&self, extra: &Option<Vec<IriRef>>) -> CResult<Vec<Pred>> {
269 if let Some(extra) = extra {
270 let mut vs = Vec::new();
271 for iri in extra {
272 let nm = cnv_iri_ref(iri)?;
273 vs.push(Pred::new(nm));
274 }
275 Ok(vs)
276 } else {
277 Ok(Vec::new())
278 }
279 }
280
281 fn cnv_sem_acts(sem_acts: &Option<Vec<ast::SemAct>>) -> Vec<SemAct> {
282 if let Some(_vs) = sem_acts {
283 Vec::new()
285 } else {
286 Vec::new()
287 }
288 }
289
290 fn cnv_annotations(annotations: &Option<Vec<ast::Annotation>>) -> Vec<Annotation> {
291 if let Some(_anns) = annotations {
292 Vec::new()
294 } else {
295 Vec::new()
296 }
297 }
298
299 fn triple_expr2rbe(
300 &self,
301 triple_expr: &ast::TripleExpr,
302 compiled_schema: &mut SchemaIR,
303 current_table: &mut RbeTable<Pred, Node, ShapeLabelIdx>,
304 ) -> CResult<Rbe<Component>> {
305 match triple_expr {
306 ast::TripleExpr::EachOf {
307 id: _,
308 expressions,
309 min,
310 max,
311 sem_acts: _,
312 annotations: _,
313 } => {
314 let mut cs = Vec::new();
315 for e in expressions {
316 let c = self.triple_expr2rbe(&e.te, compiled_schema, current_table)?;
317 cs.push(c)
318 }
319 let card = self.cnv_min_max(min, max)?;
320 Ok(Self::mk_card_group(Rbe::and(cs), card))
321 }
322 ast::TripleExpr::OneOf {
323 id: _,
324 expressions,
325 min,
326 max,
327 sem_acts: _,
328 annotations: _,
329 } => {
330 let mut cs = Vec::new();
331 for e in expressions {
332 let c = self.triple_expr2rbe(&e.te, compiled_schema, current_table)?;
333 cs.push(c)
334 }
335 let card = self.cnv_min_max(min, max)?;
336 Ok(Self::mk_card_group(Rbe::or(cs), card))
337 }
338 ast::TripleExpr::TripleConstraint {
339 id: _,
340 negated: _,
341 inverse: _,
342 predicate,
343 value_expr,
344 min,
345 max,
346 sem_acts: _,
347 annotations: _,
348 } => {
349 let min = self.cnv_min(min)?;
350 let max = self.cnv_max(max)?;
351 let iri = Self::cnv_predicate(predicate)?;
352 let cond = self.value_expr2match_cond(value_expr, compiled_schema)?;
353 let c = current_table.add_component(iri, &cond);
354 Ok(Rbe::symbol(c, min.value, max))
355 }
356 ast::TripleExpr::TripleExprRef(r) => Err(SchemaIRError::Todo {
357 msg: format!("TripleExprRef {r:?}"),
358 }),
359 }
360 }
361
362 fn cnv_predicate(predicate: &IriRef) -> CResult<Pred> {
363 match predicate {
364 IriRef::Iri(iri) => Ok(Pred::from(iri.clone())),
365 IriRef::Prefixed { prefix, local } => Err(SchemaIRError::Internal {
366 msg: format!(
367 "Cannot convert prefixed {prefix}:{local} to predicate without context"
368 ),
369 }),
370 }
371 }
372
373 fn cnv_min_max(&self, min: &Option<i32>, max: &Option<i32>) -> CResult<Cardinality> {
374 let min = self.cnv_min(min)?;
375 let max = self.cnv_max(max)?;
376 Ok(Cardinality::from(min, max))
377 }
378
379 fn mk_card_group(rbe: Rbe<Component>, card: Cardinality) -> Rbe<Component> {
380 match &card {
381 c if c.is_1_1() => rbe,
382 c if c.is_star() => Rbe::Star {
383 value: Box::new(rbe),
384 },
385 c if c.is_plus() => Rbe::Plus {
386 value: Box::new(rbe),
387 },
388 _c => Rbe::Repeat {
389 value: Box::new(rbe),
390 card,
391 },
392 }
393 }
394
395 fn cnv_min(&self, min: &Option<i32>) -> CResult<Min> {
396 match min {
397 Some(min) if *min < 0 => Err(SchemaIRError::MinLessZero { min: *min }),
398 Some(min) => Ok(Min::from(*min)),
399 None => Ok(Min::from(1)),
400 }
401 }
402
403 fn cnv_max(&self, max: &Option<i32>) -> CResult<Max> {
404 match *max {
405 Some(-1) => Ok(Max::Unbounded),
406 Some(max) if max < -1 => Err(SchemaIRError::MaxIncorrect { max }),
407 Some(max) => Ok(Max::from(max)),
408 None => Ok(Max::from(1)),
409 }
410 }
411
412 fn value_expr2match_cond(
413 &self,
414 ve: &Option<Box<ast::ShapeExpr>>,
415 compiled_schema: &mut SchemaIR,
416 ) -> CResult<Cond> {
417 if let Some(se) = ve.as_deref() {
418 match se {
419 ast::ShapeExpr::NodeConstraint(nc) => self.cnv_node_constraint(
420 &nc.node_kind(),
421 &nc.datatype(),
422 &nc.xs_facet(),
423 &nc.values(),
424 ),
425
426 ast::ShapeExpr::Ref(sref) => {
427 let idx = self.ref2idx(sref, compiled_schema)?;
428 Ok(mk_cond_ref(idx))
429 }
430 ast::ShapeExpr::Shape { .. } => todo("value_expr2match_cond: Shape"),
431 ast::ShapeExpr::ShapeAnd { .. } => todo("value_expr2match_cond: ShapeOr"),
432 ast::ShapeExpr::ShapeOr { .. } => todo("value_expr2match_cond: ShapeOr"),
433 ast::ShapeExpr::ShapeNot { shape_expr } => {
434 let new_idx = compiled_schema.new_index();
435 let se = self.compile_shape_expr(&shape_expr.se, &new_idx, compiled_schema)?;
436 let display = match compiled_schema.find_shape_idx(&new_idx) {
437 None => "internal NOT".to_string(),
438 Some((Some(label), _)) => compiled_schema.show_label(label),
439 Some((None, _)) => "internal NOT with some shape expr".to_string(),
440 };
441 let not_se = ShapeExpr::ShapeNot {
442 expr: Box::new(se),
443 display,
444 };
445 compiled_schema.replace_shape(&new_idx, not_se);
446 Ok(mk_cond_ref(new_idx))
447 }
448 ast::ShapeExpr::External => todo("value_expr2match_cond: ShapeExternal"),
449 }
450 } else {
451 Ok(MatchCond::single(SingleCond::new().with_name(".")))
452 }
453 }
454
455 fn get_preds_shape(shape: &ast::Shape) -> Vec<Pred> {
465 match shape.triple_expr() {
466 None => Vec::new(),
467 Some(te) => Self::get_preds_triple_expr(&te),
468 }
469 }
470
471 fn get_preds_triple_expr(te: &ast::TripleExpr) -> Vec<Pred> {
472 match te {
473 ast::TripleExpr::EachOf { expressions, .. } => expressions
474 .iter()
475 .flat_map(|te| Self::get_preds_triple_expr(&te.te))
476 .collect(),
477 ast::TripleExpr::OneOf { expressions, .. } => expressions
478 .iter()
479 .flat_map(|te| Self::get_preds_triple_expr(&te.te))
480 .collect(),
481 ast::TripleExpr::TripleConstraint { predicate, .. } => {
482 let pred = iri_ref2iri_s(predicate);
483 vec![Pred::new(pred)]
484 }
485 ast::TripleExpr::TripleExprRef(_) => todo!(),
486 }
487 }
488
489 fn get_references_shape(
490 &self,
491 shape: &ast::Shape,
492 schema: &SchemaIR,
493 ) -> HashMap<Pred, Vec<ShapeLabelIdx>> {
494 match shape.triple_expr() {
495 None => HashMap::new(),
496 Some(te) => self.get_references_triple_expr(&te, schema),
497 }
498 }
499
500 fn get_references_triple_expr(
501 &self,
502 te: &ast::TripleExpr,
503 schema: &SchemaIR,
504 ) -> HashMap<Pred, Vec<ShapeLabelIdx>> {
505 match te {
506 ast::TripleExpr::EachOf { expressions, .. } => {
507 expressions.iter().fold(HashMap::new(), |mut acc, te| {
508 let refs = self.get_references_triple_expr(&te.te, schema);
509 for (pred, idxs) in refs {
510 acc.entry(pred).or_default().extend(idxs);
511 }
512 acc
513 })
514 }
515 ast::TripleExpr::OneOf { expressions, .. } => {
516 expressions.iter().fold(HashMap::new(), |mut acc, te| {
517 let refs = self.get_references_triple_expr(&te.te, schema);
518 for (pred, idxs) in refs {
519 acc.entry(pred).or_default().extend(idxs);
520 }
521 acc
522 })
523 }
524 ast::TripleExpr::TripleConstraint {
525 predicate,
526 value_expr,
527 ..
528 } => {
529 let pred = iri_ref2iri_s(predicate);
530 match value_expr {
531 Some(ve) => match ve.as_ref() {
532 ast::ShapeExpr::Ref(sref) => {
533 let label =
534 self.shape_expr_label_to_shape_label(sref)
535 .unwrap_or_else(|_| {
536 panic!("Convert shape label to IR label {sref}")
537 });
538 let idx = schema.get_shape_label_idx(&label).unwrap_or_else(|_| {
539 panic!("Failed to get shape label index for {label}")
540 });
541 let mut map = HashMap::new();
542 map.insert(Pred::new(pred), vec![idx]);
543 map
544 }
545 _ => HashMap::new(),
546 },
547 None => HashMap::new(),
548 }
549 }
550 ast::TripleExpr::TripleExprRef(_) => todo!(),
551 }
552 }
553}
554
555fn iri_ref2iri_s(iri_ref: &IriRef) -> IriS {
556 match iri_ref {
557 IriRef::Iri(iri) => iri.clone(),
558 IriRef::Prefixed { prefix, local } => {
559 panic!("Compiling schema...found prefixed iri: {prefix}:{local}")
560 }
561 }
562}
563
564fn node_constraint2match_cond(
565 node_kind: &Option<ast::NodeKind>,
566 datatype: &Option<IriRef>,
567 xs_facet: &Option<Vec<ast::XsFacet>>,
568 values: &Option<ValueSet>,
569) -> CResult<Cond> {
570 let c1: Option<Cond> = node_kind.as_ref().map(node_kind2match_cond);
571 let c2 = datatype.as_ref().map(datatype2match_cond).transpose()?;
572 let c3 = xs_facet.as_ref().map(xs_facets2match_cond);
573 let c4 = values.as_ref().map(|vs| valueset2match_cond(vs.clone()));
574 let os = vec![c1, c2, c3, c4];
575 Ok(options2match_cond(os))
576}
577
578fn node_kind2match_cond(nodekind: &ast::NodeKind) -> Cond {
579 mk_cond_nodekind(nodekind.clone())
580}
581
582fn datatype2match_cond(datatype: &IriRef) -> CResult<Cond> {
583 Ok(mk_cond_datatype(datatype))
585}
586
587fn xs_facets2match_cond(xs_facets: &Vec<ast::XsFacet>) -> Cond {
588 let mut conds = Vec::new();
589 for xs_facet in xs_facets {
590 conds.push(xs_facet2match_cond(xs_facet))
591 }
592 MatchCond::And(conds)
593}
594
595fn xs_facet2match_cond(xs_facet: &ast::XsFacet) -> Cond {
596 match xs_facet {
597 ast::XsFacet::StringFacet(sf) => string_facet_to_match_cond(sf),
598 ast::XsFacet::NumericFacet(nf) => numeric_facet_to_match_cond(nf),
599 }
600}
601
602fn string_facet_to_match_cond(sf: &ast::StringFacet) -> Cond {
603 match sf {
604 ast::StringFacet::Length(len) => mk_cond_length(*len),
605 ast::StringFacet::MinLength(len) => mk_cond_min_length(*len),
606 ast::StringFacet::MaxLength(len) => mk_cond_max_length(*len),
607 ast::StringFacet::Pattern(_) => todo!(),
608 }
609}
610
611fn numeric_facet_to_match_cond(nf: &ast::NumericFacet) -> Cond {
612 match nf {
613 ast::NumericFacet::MinInclusive(_min) => todo!(),
614 ast::NumericFacet::MinExclusive(_) => todo!(),
615 ast::NumericFacet::MaxInclusive(_) => todo!(),
616 ast::NumericFacet::MaxExclusive(_) => todo!(),
617 ast::NumericFacet::TotalDigits(_) => todo!(),
618 ast::NumericFacet::FractionDigits(_) => todo!(),
619 }
620}
621
622fn valueset2match_cond(vs: ValueSet) -> Cond {
623 mk_cond_value_set(vs)
624}
625
626fn options2match_cond<T: IntoIterator<Item = Option<Cond>>>(os: T) -> Cond {
627 let vec: Vec<Cond> = os.into_iter().flatten().collect();
628 match &vec[..] {
629 [] => MatchCond::empty(),
630 [c] => c.clone(),
631 _ => MatchCond::And(vec),
632 }
633}
634
635fn mk_cond_ref(idx: ShapeLabelIdx) -> Cond {
636 MatchCond::ref_(idx)
637}
638
639fn mk_cond_datatype(datatype: &IriRef) -> Cond {
640 let dt = datatype.clone();
641 MatchCond::single(
642 SingleCond::new()
643 .with_name(format!("datatype({dt})").as_str())
644 .with_cond(move |value: &Node| match check_node_datatype(value, &dt) {
645 Ok(_) => Ok(Pending::new()),
646 Err(err) => Err(RbeError::MsgError {
647 msg: format!("Datatype error: {err}"),
648 }),
649 }),
650 )
651}
652
653fn mk_cond_length(len: usize) -> Cond {
654 MatchCond::single(
655 SingleCond::new()
656 .with_name(format!("length({len})").as_str())
657 .with_cond(move |value: &Node| match check_node_length(value, len) {
658 Ok(_) => Ok(Pending::new()),
659 Err(err) => Err(RbeError::MsgError {
660 msg: format!("Length error: {err}"),
661 }),
662 }),
663 )
664}
665
666fn mk_cond_min_length(len: usize) -> Cond {
667 MatchCond::single(
668 SingleCond::new()
669 .with_name(format!("minLength({len})").as_str())
670 .with_cond(
671 move |value: &Node| match check_node_min_length(value, len) {
672 Ok(_) => Ok(Pending::new()),
673 Err(err) => Err(RbeError::MsgError {
674 msg: format!("MinLength error: {err}"),
675 }),
676 },
677 ),
678 )
679}
680
681fn mk_cond_max_length(len: usize) -> Cond {
682 MatchCond::simple(format!("maxLength({len})").as_str(), move |value: &Node| {
683 match check_node_max_length(value, len) {
684 Ok(_) => Ok(Pending::new()),
685 Err(err) => Err(RbeError::MsgError {
686 msg: format!("MaxLength error: {err}"),
687 }),
688 }
689 })
690}
691
692fn mk_cond_nodekind(nodekind: ast::NodeKind) -> Cond {
693 MatchCond::single(
694 SingleCond::new()
695 .with_name(format!("nodekind({nodekind})").as_str())
696 .with_cond(
697 move |value: &Node| match check_node_node_kind(value, &nodekind) {
698 Ok(_) => Ok(Pending::empty()),
699 Err(err) => Err(RbeError::MsgError {
700 msg: format!("NodeKind Error: {err}"),
701 }),
702 },
703 ),
704 )
705}
706
707fn iri_ref_2_shape_label(id: &IriRef) -> CResult<ShapeLabel> {
708 match id {
709 IriRef::Iri(iri) => Ok(ShapeLabel::Iri(iri.clone())),
710 IriRef::Prefixed { prefix, local } => Err(SchemaIRError::IriRef2ShapeLabelError {
711 prefix: prefix.clone(),
712 local: local.clone(),
713 }),
714 }
715}
716
717fn mk_cond_value_set(value_set: ValueSet) -> Cond {
718 MatchCond::single(
719 SingleCond::new()
720 .with_name(format!("{}", value_set).as_str())
721 .with_cond(move |node: &Node| {
722 if value_set.check_value(node.as_object()) {
723 Ok(Pending::empty())
724 } else {
725 Err(RbeError::MsgError {
726 msg: format!("Values failed: {node} not in {value_set}"),
727 })
728 }
729 }),
730 )
731}
732
733fn create_value_set(values: &Vec<ast::ValueSetValue>) -> CResult<ValueSet> {
734 let mut vs = ValueSet::new();
735 for v in values {
736 let cvalue = cnv_value(v)?;
737 vs.add_value(cvalue)
738 }
739 Ok(vs)
740}
741
742fn cnv_value(v: &ast::ValueSetValue) -> CResult<ValueSetValue> {
743 match &v {
744 ast::ValueSetValue::IriStem { stem, .. } => {
745 let cnv_stem = cnv_iri_ref(stem)?;
746 Ok(ValueSetValue::IriStem { stem: cnv_stem })
747 }
748 ast::ValueSetValue::ObjectValue(ovw) => {
749 let ov = cnv_object_value(ovw)?;
750 Ok(ValueSetValue::ObjectValue(ov))
751 }
752 ast::ValueSetValue::Language { language_tag, .. } => Ok(ValueSetValue::Language {
753 language_tag: language_tag.to_string(),
754 }),
755 ast::ValueSetValue::LiteralStem { stem, .. } => Ok(ValueSetValue::LiteralStem {
756 stem: stem.to_string(),
757 }),
758 ast::ValueSetValue::LiteralStemRange { .. } => {
759 todo!()
760 }
764 _ => todo!(),
765 }
766}
767
768fn cnv_object_value(ov: &ast::ObjectValue) -> CResult<ObjectValue> {
835 match ov {
836 ast::ObjectValue::IriRef(ir) => {
837 let iri = cnv_iri_ref(ir)?;
838 Ok(ObjectValue::IriRef(iri))
839 }
840 ast::ObjectValue::Literal(lit) => Ok(ObjectValue::ObjectLiteral(lit.clone())),
841 }
842}
843
844fn check_node_node_kind(node: &Node, nk: &ast::NodeKind) -> CResult<()> {
856 match (nk, node.as_object()) {
857 (ast::NodeKind::Iri, Object::Iri { .. }) => Ok(()),
858 (ast::NodeKind::Iri, _) => Err(SchemaIRError::NodeKindIri { node: node.clone() }),
859 (ast::NodeKind::BNode, Object::BlankNode(_)) => Ok(()),
860 (ast::NodeKind::BNode, _) => Err(SchemaIRError::NodeKindBNode { node: node.clone() }),
861 (ast::NodeKind::Literal, Object::Literal(_)) => Ok(()),
862 (ast::NodeKind::Literal, _) => Err(SchemaIRError::NodeKindLiteral { node: node.clone() }),
863 (ast::NodeKind::NonLiteral, Object::BlankNode(_)) => Ok(()),
864 (ast::NodeKind::NonLiteral, Object::Iri { .. }) => Ok(()),
865 (ast::NodeKind::NonLiteral, _) => {
866 Err(SchemaIRError::NodeKindNonLiteral { node: node.clone() })
867 }
868 }
869}
870
871fn check_node_datatype(node: &Node, dt: &IriRef) -> CResult<()> {
881 debug!("check_node_datatype: {node:?} datatype: {dt}");
882 match node.as_object() {
883 Object::Literal(Literal::DatatypeLiteral {
884 ref datatype,
885 lexical_form,
886 }) => {
887 if dt == datatype {
888 Ok(())
889 } else {
890 Err(SchemaIRError::DatatypeDontMatch {
891 expected: dt.clone(),
892 found: datatype.clone(),
893 lexical_form: lexical_form.clone(),
894 })
895 }
896 }
897 Object::Literal(Literal::StringLiteral {
898 lexical_form,
899 lang: None,
900 }) => {
901 debug!("StringLiteral...{}", *dt);
902 if *dt == *XSD_STRING {
903 debug!("datatype cond passes");
904 Ok(())
905 } else {
906 debug!("datatype cond fails: {}!={}", dt, *XSD_STRING);
907 Err(SchemaIRError::DatatypeDontMatchString {
908 expected: dt.clone(),
909 lexical_form: lexical_form.clone(),
910 })
911 }
912 }
913 Object::Literal(Literal::StringLiteral {
914 lexical_form,
915 lang: Some(lang),
916 }) => {
917 if *dt == *RDF_LANG_STRING {
918 Ok(())
919 } else {
920 Err(SchemaIRError::DatatypeDontMatchLangString {
921 lexical_form: lexical_form.clone(),
922 lang: Box::new(lang.clone()),
923 })
924 }
925 }
926 _ => Err(SchemaIRError::DatatypeNoLiteral {
927 expected: Box::new(dt.clone()),
928 node: Box::new(node.clone()),
929 }),
930 }
931}
932
933fn check_node_length(node: &Node, len: usize) -> CResult<()> {
934 debug!("check_node_length: {node:?} length: {len}");
935 let node_length = node.length();
936 if node_length == len {
937 Ok(())
938 } else {
939 Err(SchemaIRError::LengthError {
940 expected: len,
941 found: node_length,
942 node: format!("{node}"),
943 })
944 }
945}
946
947fn check_node_min_length(node: &Node, len: usize) -> CResult<()> {
948 debug!("check_node_min_length: {node:?} min_length: {len}");
949 let node_length = node.length();
950 if node_length >= len {
951 Ok(())
952 } else {
953 Err(SchemaIRError::MinLengthError {
954 expected: len,
955 found: node_length,
956 node: format!("{node}"),
957 })
958 }
959}
960
961fn check_node_max_length(node: &Node, len: usize) -> CResult<()> {
962 debug!("check_node_max_length: {node:?} max_length: {len}");
963 let node_length = node.length();
964 if node_length <= len {
965 Ok(())
966 } else {
967 Err(SchemaIRError::MaxLengthError {
968 expected: len,
969 found: node_length,
970 node: format!("{node}"),
971 })
972 }
973}
974
975fn todo<A>(str: &str) -> CResult<A> {
1001 Err(SchemaIRError::Todo {
1002 msg: str.to_string(),
1003 })
1004}
1005
1006fn cnv_iri_ref(iri: &IriRef) -> Result<IriS, SchemaIRError> {
1007 match iri {
1008 IriRef::Iri(iri) => Ok(iri.clone()),
1009 _ => Err(SchemaIRError::Internal {
1010 msg: format!("Cannot convert {iri} to Iri"),
1011 }),
1012 }
1013}