shex_compact/
shex_grammar.rs

1use crate::grammar_structs::{
2    Cardinality, NumericLength, NumericRange, Qualifier, SenseFlags, ShExStatement,
3};
4use crate::{
5    map_error, shex_parser_error::ParseError as ShExParseError, tag_no_case_tws, token, token_tws,
6    traced, tws0, IRes, Span,
7};
8use iri_s::IriS;
9use nom::{
10    branch::alt,
11    bytes::complete::{tag, tag_no_case, take_while, take_while1},
12    character::complete::{alpha1, alphanumeric1, char, digit0, digit1, none_of, one_of, satisfy},
13    combinator::{cut, map, map_res, opt, recognize},
14    error::ErrorKind,
15    error_position,
16    multi::{count, fold_many0, many0, many1},
17    sequence::{delimited, pair, preceded, tuple},
18    Err, InputTake,
19};
20use regex::Regex;
21use shex_ast::iri_ref_or_wildcard::IriRefOrWildcard;
22use shex_ast::string_or_wildcard::StringOrWildcard;
23use shex_ast::IriOrStr;
24use shex_ast::{
25    object_value::ObjectValue, value_set_value::ValueSetValue, Annotation, BNode, IriExclusion,
26    LangOrWildcard, LanguageExclusion, LiteralExclusion, NodeConstraint, NodeKind, NumericFacet,
27    Pattern, SemAct, Shape, ShapeExpr, ShapeExprLabel, StringFacet, TripleExpr, TripleExprLabel,
28    XsFacet,
29};
30use std::{collections::VecDeque, fmt::Debug, num::ParseIntError};
31use thiserror::Error;
32
33use lazy_regex::{regex, Lazy};
34use nom_locate::LocatedSpan;
35use prefixmap::IriRef;
36use srdf::{lang::Lang, literal::Literal, numeric_literal::NumericLiteral, RDF_TYPE_STR};
37
38/// `[1] shexDoc ::= directive* ((notStartAction | startActions) statement*)?`
39pub(crate) fn shex_statement<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
40    traced(
41        "shex_statement",
42        map_error(
43            move |i| alt((directive, start(), shape_expr_decl(), start_actions))(i),
44            || ShExParseError::ExpectedStatement,
45        ),
46    )
47}
48
49/*
50fn empty(i: Span) -> IRes<ShExStatement> {
51    let (i, _) = tws0(i)?;
52    Ok((i, ShExStatement::Empty))
53}
54*/
55
56/*pub(crate) fn shex_statement<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Vec<ShExStatement>> {
57    traced("shex_statement", move |i| {
58        let (i, (ds, _, maybe_sts)) = tuple((directives, tws0, opt(rest_shex_statements)))(i)?;
59        let mut result = Vec::new();
60        result.extend(ds);
61        match maybe_sts {
62            None => {}
63            Some(sts) => {
64                result.extend(sts);
65            }
66        }
67        Ok((i, result))
68    })
69}
70
71/// From [1] rest_shex_statements = ((notStartAction | startActions) statement*)
72fn rest_shex_statements(i: Span) -> IRes<Vec<ShExStatement>> {
73    let (i, (s, _, ss, _)) = tuple((
74        alt((not_start_action, start_actions)),
75        tws0,
76        statements,
77        tws0,
78    ))(i)?;
79    let mut rs = vec![s];
80    rs.extend(ss);
81    Ok((i, rs))
82}
83
84fn directives(i: Span) -> IRes<Vec<ShExStatement>> {
85    let (i, vs) = many1(
86        //tuple((
87            directive
88        //    ,
89        //    tws0
90        //))
91    )(i)?;
92    // let mut rs = Vec::new();
93    /*for v in vs {
94        let (d, _) = v;
95        rs.push(d);
96    }*/
97    Ok((i, vs))
98}
99
100fn statements(i: Span) -> IRes<Vec<ShExStatement>> {
101    many0(statement)(i)
102} */
103
104/// `[2] directive ::= baseDecl | prefixDecl | importDecl`
105fn directive(i: Span) -> IRes<ShExStatement> {
106    alt((base_decl(), prefix_decl(), import_decl()))(i)
107}
108
109/// `[3] baseDecl ::= "BASE" IRIREF`
110fn base_decl<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
111    traced(
112        "base_decl",
113        map_error(
114            move |i| {
115                let (i, (_, _, iri_ref)) = tuple((tag_no_case("BASE"), tws0, cut(iri_ref)))(i)?;
116                Ok((i, ShExStatement::BaseDecl { iri: iri_ref }))
117            },
118            || ShExParseError::ExpectedBaseDecl,
119        ),
120    )
121}
122
123/// [4] `prefixDecl ::= "PREFIX" PNAME_NS IRIREF`
124fn prefix_decl<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
125    traced(
126        "prefix_decl",
127        map_error(
128            move |i| {
129                let (i, (_, _, pname_ns, _, iri_ref)) = tuple((
130                    tag_no_case("PREFIX"),
131                    tws0,
132                    cut(pname_ns),
133                    tws0,
134                    cut(iri_ref),
135                ))(i)?;
136                Ok((
137                    i,
138                    ShExStatement::PrefixDecl {
139                        alias: pname_ns.fragment(),
140                        iri: iri_ref,
141                    },
142                ))
143            },
144            || ShExParseError::ExpectedPrefixDecl,
145        ),
146    )
147}
148
149/// `[4½] importDecl ::= "IMPORT" IRIREF`
150fn import_decl<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
151    traced(
152        "import_decl",
153        map_error(
154            move |i| {
155                let (i, (_, _, iri_or_str)) =
156                    tuple((tag_no_case("IMPORT"), tws0, cut(iri_ref_or_str)))(i)?;
157                tracing::debug!("grammar: Import {iri_or_str:?}");
158                Ok((i, ShExStatement::ImportDecl { iri: iri_or_str }))
159            },
160            || ShExParseError::ExpectedImportDecl,
161        ),
162    )
163}
164/*
165/// `[5] notStartAction	::= start | shapeExprDecl`
166fn not_start_action(i: Span) -> IRes<ShExStatement> {
167    alt((start(), shape_expr_decl()))(i)
168}
169*/
170/// `[6] start ::= "start" '=' inlineShapeExpression`
171fn start<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
172    map_error(
173        move |i| {
174            let (i, (_, _, _, _, se)) = tuple((
175                tag_no_case("START"),
176                tws0,
177                cut(char('=')),
178                tws0,
179                cut(inline_shape_expression()),
180            ))(i)?;
181            Ok((i, ShExStatement::StartDecl { shape_expr: se }))
182        },
183        || ShExParseError::ExpectedStart,
184    )
185}
186
187/// `[7] startActions ::= codeDecl+`
188fn start_actions(i: Span) -> IRes<ShExStatement> {
189    let (i, cs) = many1(code_decl())(i)?;
190    Ok((i, ShExStatement::StartActions { actions: cs }))
191}
192/*
193/// `[8]   	statement	   ::=   	directive | notStartAction`
194fn statement(i: Span) -> IRes<ShExStatement> {
195    alt((directive, not_start_action))(i)
196}
197*/
198/// `[9] shapeExprDecl ::= shapeExprLabel (shapeExpression | "EXTERNAL")`
199fn shape_expr_decl<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShExStatement<'a>> {
200    traced(
201        "shape_expr_decl",
202        map_error(
203            move |i| {
204                let (i, (maybe_abstract, shape_label, _, shape_expr)) = tuple((
205                    opt(tag_no_case_tws("abstract")),
206                    shape_expr_label,
207                    tws0,
208                    cut(shape_expr_or_external()),
209                ))(i)?;
210                let is_abstract = maybe_abstract.is_some();
211                Ok((
212                    i,
213                    ShExStatement::ShapeDecl {
214                        is_abstract,
215                        shape_label,
216                        shape_expr,
217                    },
218                ))
219            },
220            || ShExParseError::ExpectedShapeExprDecl,
221        ),
222    )
223}
224
225fn shape_expr_or_external<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
226    map_error(
227        move |i| alt((shape_expression(), external))(i),
228        || ShExParseError::ShapeExprOrExternal,
229    )
230}
231
232fn external(i: Span) -> IRes<ShapeExpr> {
233    let (i, _) = tag_no_case("EXTERNAL")(i)?;
234    Ok((i, ShapeExpr::external()))
235}
236
237/// `[10] shapeExpression ::= shapeOr`
238fn shape_expression<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
239    traced(
240        "ShapeExpr",
241        map_error(move |i| shape_or(i), || ShExParseError::ExpectedShapeExpr),
242    )
243}
244
245/// `[11] inlineShapeExpression ::= inlineShapeOr`
246fn inline_shape_expression<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
247    traced(
248        "inline_shape_expr",
249        map_error(
250            move |i| inline_shape_or(i),
251            || ShExParseError::ExpectedInlineShapeExpr,
252        ),
253    )
254}
255
256/// `[12] shapeOr ::= shapeAnd ("OR" shapeAnd)*`
257fn shape_or(i: Span<'_>) -> IRes<'_, ShapeExpr> {
258    many1_sep(shape_and, symbol("OR"), make_shape_or, i)
259}
260
261fn make_shape_or(ses: Vec<ShapeExpr>) -> ShapeExpr {
262    if ses.len() == 1 {
263        ses[0].clone()
264    } else {
265        ShapeExpr::or(ses)
266    }
267}
268
269/// `[13] inlineShapeOr ::= inlineShapeAnd ("OR" inlineShapeAnd)*`
270fn inline_shape_or(i: Span) -> IRes<ShapeExpr> {
271    many1_sep(inline_shape_and, symbol("OR"), make_shape_or, i)
272}
273
274/// `[14] shapeAnd ::= shapeNot ("AND" shapeNot)*`
275fn shape_and(i: Span) -> IRes<ShapeExpr> {
276    many1_sep(shape_not, symbol("AND"), make_shape_and, i)
277}
278
279fn make_shape_and(ses: Vec<ShapeExpr>) -> ShapeExpr {
280    if ses.len() == 1 {
281        ses[0].clone()
282    } else {
283        ShapeExpr::and(ses)
284    }
285}
286
287/// `[15] inlineShapeAnd ::= inlineShapeNot ("AND" inlineShapeNot)*`
288fn inline_shape_and(i: Span) -> IRes<ShapeExpr> {
289    many1_sep(inline_shape_not, symbol("AND"), make_shape_and, i)
290}
291
292/// `[16] shapeNot ::= "NOT"? shapeAtom`
293fn shape_not(i: Span) -> IRes<ShapeExpr> {
294    let (i, maybe) = opt(symbol("NOT"))(i)?;
295    let (i, se) = shape_atom()(i)?;
296    match maybe {
297        None => Ok((i, se)),
298        Some(_) => Ok((i, ShapeExpr::shape_not(se))),
299    }
300}
301
302/// `[17] inlineShapeNot ::= "NOT"? inlineShapeAtom`
303fn inline_shape_not(i: Span) -> IRes<ShapeExpr> {
304    let (i, maybe) = opt(symbol("NOT"))(i)?;
305    let (i, se) = inline_shape_atom()(i)?;
306    match maybe {
307        None => Ok((i, se)),
308        Some(_) => Ok((i, ShapeExpr::shape_not(se))),
309    }
310}
311
312/// `[18] shapeAtom ::= nonLitNodeConstraint shapeOrRef?`
313/// `| litNodeConstraint`
314/// `| shapeOrRef nonLitNodeConstraint?`
315/// `| '(' shapeExpression ')'`
316/// `| '.'`
317fn shape_atom<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
318    traced(
319        "shape_atom",
320        map_error(
321            move |i| {
322                alt((
323                    non_lit_opt_shape_or_ref(),
324                    lit_node_constraint_shape_expr(),
325                    shape_opt_non_lit,
326                    paren_shape_expr,
327                    dot,
328                ))(i)
329            },
330            || ShExParseError::ShapeAtom,
331        ),
332    )
333}
334
335fn non_lit_opt_shape_or_ref<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
336    traced(
337        "non_lit_opt_shape_or_ref",
338        map_error(
339            move |i| {
340                let (i, (non_lit, _, maybe_se)) =
341                    tuple((non_lit_node_constraint, tws0, cut(opt(shape_or_ref()))))(i)?;
342                let nc = ShapeExpr::node_constraint(non_lit);
343                let se_result = match maybe_se {
344                    None => nc,
345                    Some(se) => match se {
346                        ShapeExpr::ShapeAnd { shape_exprs } => {
347                            let mut new_ses = vec![nc];
348                            for sew in shape_exprs {
349                                new_ses.push(sew.se)
350                            }
351                            ShapeExpr::and(new_ses)
352                        }
353                        other => make_shape_and(vec![nc, other]),
354                    },
355                };
356                Ok((i, se_result))
357            },
358            || ShExParseError::NonLitNodeConstraintOptShapeOrRef,
359        ),
360    )
361}
362
363/// `From [18] `shape_opt_non_lit ::= shapeOrRef nonLitNodeConstraint?`
364fn shape_opt_non_lit(i: Span) -> IRes<ShapeExpr> {
365    let (i, se) = shape_or_ref()(i)?;
366    let (i, maybe_non_lit) = opt(non_lit_node_constraint)(i)?;
367    match maybe_non_lit {
368        None => Ok((i, se)),
369        Some(nl) => Ok((i, ShapeExpr::and(vec![se, ShapeExpr::node_constraint(nl)]))),
370    }
371}
372
373/// `[20] inlineShapeAtom ::= nonLitNodeConstraint inlineShapeOrRef?`
374/// `                      | litNodeConstraint`
375/// `                      | inlineShapeOrRef nonLitNodeConstraint?`
376/// `                      | '(' shapeExpression ')'`
377/// `                      | '.'`
378fn inline_shape_atom<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
379    traced(
380        "inline_shape_atom",
381        map_error(
382            move |i| {
383                alt((
384                    non_lit_inline_opt_shape_or_ref(),
385                    lit_node_constraint_shape_expr(),
386                    inline_shape_or_ref_opt_non_lit,
387                    paren_shape_expr,
388                    dot,
389                ))(i)
390            },
391            || ShExParseError::ExpectedInlineShapeAtom,
392        ),
393    )
394}
395
396/// From [20] `non_lit_inline_opt_shape_or_ref = nonLitNodeConstraint inlineShapeOrRef?`
397fn non_lit_inline_opt_shape_or_ref<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
398    traced(
399        "non_lit_inline_nodeConstraint InlineShapeOr?",
400        map_error(
401            move |i| {
402                let (i, (non_lit, _, maybe_se)) =
403                    tuple((non_lit_node_constraint, tws0, opt(inline_shape_or_ref)))(i)?;
404                let nc = ShapeExpr::node_constraint(non_lit);
405                let se_result = match maybe_se {
406                    None => nc,
407                    Some(se) => make_shape_and(vec![nc, se]),
408                };
409                Ok((i, se_result))
410            },
411            || ShExParseError::NonLitInlineNodeConstraintOptShapeOrRef,
412        ),
413    )
414}
415
416/// `from [20] `inline_shape_or_ref_opt_non_lit ::= inlineShapeOrRef nonLitNodeConstraint?`
417fn inline_shape_or_ref_opt_non_lit(i: Span) -> IRes<ShapeExpr> {
418    let (i, se) = inline_shape_or_ref(i)?;
419    let (i, maybe_non_lit) = opt(non_lit_node_constraint)(i)?;
420    match maybe_non_lit {
421        None => Ok((i, se)),
422        Some(nl) => Ok((i, ShapeExpr::and(vec![se, ShapeExpr::node_constraint(nl)]))),
423    }
424}
425
426fn lit_node_constraint_shape_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
427    traced(
428        "lit_node_constraint",
429        map_error(
430            move |i| {
431                let (i, nc) = lit_node_constraint()(i)?;
432                Ok((i, ShapeExpr::NodeConstraint(nc)))
433            },
434            || ShExParseError::LitNodeConstraint,
435        ),
436    )
437}
438
439fn paren_shape_expr(i: Span) -> IRes<ShapeExpr> {
440    let (i, (_, _, se, _, _)) = tuple((char('('), tws0, shape_expression(), tws0, char(')')))(i)?;
441    Ok((i, se))
442}
443
444fn dot(i: Span) -> IRes<ShapeExpr> {
445    let (i, (_, _)) = tuple((tws0, char('.')))(i)?;
446    Ok((i, ShapeExpr::any()))
447}
448
449/// `[21] shapeOrRef ::= shapeDefinition | shapeRef`
450fn shape_or_ref<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
451    traced(
452        "shape_or_ref",
453        map_error(
454            move |i| alt((shape_definition(), map(shape_ref, ShapeExpr::Ref)))(i),
455            || ShExParseError::ExpectedShapeOrRef,
456        ),
457    )
458}
459
460/// `[22] inlineShapeOrRef ::= inlineShapeDefinition | shapeRef`
461fn inline_shape_or_ref(i: Span) -> IRes<ShapeExpr> {
462    alt((inline_shape_definition, map(shape_ref, ShapeExpr::Ref)))(i)
463}
464
465/// `[23] shapeRef ::= ATPNAME_LN | ATPNAME_NS | '@' shapeExprLabel`
466fn shape_ref(i: Span) -> IRes<ShapeExprLabel> {
467    alt((at_pname_ln, at_pname_ns, at_shape_expr_label))(i)
468}
469
470fn at_shape_expr_label(i: Span) -> IRes<ShapeExprLabel> {
471    let (i, (_, label)) = tuple((char('@'), shape_expr_label))(i)?;
472    Ok((i, label))
473}
474
475/// `[24] litNodeConstraint ::= "LITERAL" xsFacet*
476/// | datatype xsFacet*
477/// | valueSet xsFacet*
478/// | numericFacet+`
479fn lit_node_constraint<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NodeConstraint> {
480    traced(
481        "lit_node_constraint",
482        map_error(
483            move |i| {
484                alt((
485                    literal_facets(),
486                    datatype_facets(),
487                    value_set_facets(),
488                    numeric_facets,
489                ))(i)
490            },
491            || ShExParseError::LitNodeConstraint,
492        ),
493    )
494}
495
496fn literal_facets<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NodeConstraint> {
497    traced("literal_facets", move |i| {
498        let (i, (_, _, facets)) = tuple((tag_no_case("LITERAL"), tws0, facets()))(i)?;
499        Ok((
500            i,
501            NodeConstraint::new()
502                .with_node_kind(NodeKind::Literal)
503                .with_xsfacets(facets),
504        ))
505    })
506}
507
508fn datatype_facets<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NodeConstraint> {
509    traced(
510        "datatype_facets",
511        map_error(
512            move |i| {
513                let (i, (dt, _, facets)) = tuple((datatype, tws0, facets()))(i)?;
514                Ok((i, dt.with_xsfacets(facets)))
515            },
516            || ShExParseError::DatatypeFacets,
517        ),
518    )
519}
520
521fn value_set_facets<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NodeConstraint> {
522    traced(
523        "value_set_facets",
524        map_error(
525            move |i| {
526                let (i, (vs, _, facets)) = tuple((value_set(), tws0, facets()))(i)?;
527                Ok((i, vs.with_xsfacets(facets)))
528            },
529            || ShExParseError::ValueSetFacets,
530        ),
531    )
532}
533
534/// `from [24] numeric_facets = numericFacet+`
535fn numeric_facets(i: Span) -> IRes<NodeConstraint> {
536    map(many1(numeric_facet()), |ns| {
537        NodeConstraint::new().with_xsfacets(ns)
538    })(i)
539}
540
541fn facets<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Vec<XsFacet>> {
542    traced("facets", move |i| many0(xs_facet())(i))
543}
544
545/// `[25] nonLitNodeConstraint ::= nonLiteralKind stringFacet* | stringFacet+`
546fn non_lit_node_constraint(i: Span) -> IRes<NodeConstraint> {
547    alt((non_literal_kind_string_facets, string_facets))(i)
548}
549
550/// `from [25] non_literal_kind_string-facets = nonLiteralKind stringFacet* `
551fn non_literal_kind_string_facets(i: Span) -> IRes<NodeConstraint> {
552    let (i, (kind, facets)) = tuple((non_literal_kind, many0(string_facet)))(i)?;
553    let mut nc = NodeConstraint::new().with_node_kind(kind);
554    if !facets.is_empty() {
555        nc = nc.with_xsfacets(facets);
556    }
557    Ok((i, nc))
558}
559
560/// `from [25] string_facets = string_facet+`
561fn string_facets(i: Span) -> IRes<NodeConstraint> {
562    let (i, facets) = many1(string_facet)(i)?;
563    Ok((i, NodeConstraint::new().with_xsfacets(facets)))
564}
565
566/// `[26] nonLiteralKind ::= "IRI" | "BNODE" | "NONLITERAL"`
567fn non_literal_kind(i: Span) -> IRes<NodeKind> {
568    alt((
569        map(token_tws("IRI"), |_| NodeKind::Iri),
570        map(token_tws("BNODE"), |_| NodeKind::BNode),
571        map(token_tws("NONLITERAL"), |_| NodeKind::NonLiteral),
572    ))(i)
573}
574
575/// `[27] xsFacet ::= stringFacet | numericFacet`
576fn xs_facet<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, XsFacet> {
577    traced("xs_facet", move |i| alt((string_facet, numeric_facet()))(i))
578}
579
580/// `[28] stringFacet ::= stringLength INTEGER | REGEXP`
581fn string_facet(i: Span) -> IRes<XsFacet> {
582    alt((
583        string_length,
584        map(regexp, |p| XsFacet::StringFacet(StringFacet::Pattern(p))),
585    ))(i)
586}
587
588// `[29]   	stringLength	   ::=   	"LENGTH" | "MINLENGTH" | "MAXLENGTH"`
589fn string_length(i: Span) -> IRes<XsFacet> {
590    alt((min_length, max_length, length))(i)
591}
592
593fn min_length(i: Span) -> IRes<XsFacet> {
594    let (i, (_, _, n)) = tuple((tag_no_case("MINLENGTH"), tws0, pos_integer))(i)?;
595    Ok((i, XsFacet::min_length(n)))
596}
597
598fn max_length(i: Span) -> IRes<XsFacet> {
599    let (i, (_, _, n)) = tuple((tag_no_case("MAXLENGTH"), tws0, pos_integer))(i)?;
600    Ok((i, XsFacet::max_length(n)))
601}
602
603fn length(i: Span) -> IRes<XsFacet> {
604    let (i, (_, _, n)) = tuple((tag_no_case("LENGTH"), tws0, pos_integer))(i)?;
605    Ok((i, XsFacet::length(n)))
606}
607
608fn pos_integer(i: Span) -> IRes<usize> {
609    let (i, n) = integer()(i)?;
610    let u: usize;
611    if n < 0 {
612        Err(Err::Error(error_position!(i, ErrorKind::Digit)))
613    } else {
614        u = n as usize;
615        Ok((i, u))
616    }
617}
618
619/// `[30] numericFacet ::= numericRange numericLiteral | numericLength INTEGER`
620fn numeric_facet<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, XsFacet> {
621    traced("numeric_facet", move |i| {
622        alt((numeric_range_lit(), numeric_length_int()))(i)
623    })
624}
625
626/// `From [30] numeric_range_lit = numericRange numericLiteral``
627fn numeric_range_lit<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, XsFacet> {
628    traced("numeric_range", move |i| {
629        let (i, (n_range, v)) = tuple((numeric_range, cut(raw_numeric_literal())))(i)?;
630        let v = match n_range {
631            NumericRange::MinInclusive => XsFacet::NumericFacet(NumericFacet::MinInclusive(v)),
632            NumericRange::MinExclusive => XsFacet::NumericFacet(NumericFacet::MinExclusive(v)),
633            NumericRange::MaxInclusive => XsFacet::NumericFacet(NumericFacet::MaxInclusive(v)),
634            NumericRange::MaxExclusive => XsFacet::NumericFacet(NumericFacet::MaxExclusive(v)),
635        };
636        Ok((i, v))
637    })
638}
639
640/// `From [30] numericLength INTEGER`
641fn numeric_length_int<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, XsFacet> {
642    traced("numeric_length_int", move |i| {
643        let (i, (numeric_length, n)) = tuple((numeric_length, integer()))(i)?;
644        let nm = match numeric_length {
645            NumericLength::FractionDigits => {
646                XsFacet::NumericFacet(NumericFacet::FractionDigits(n as usize))
647            }
648            NumericLength::TotalDigits => {
649                XsFacet::NumericFacet(NumericFacet::TotalDigits(n as usize))
650            }
651        };
652        Ok((i, nm))
653    })
654}
655
656fn numeric_length(i: Span) -> IRes<NumericLength> {
657    alt((
658        map(token_tws("TOTALDIGITS"), |_| NumericLength::TotalDigits),
659        map(token_tws("FRACTIONDIGITS"), |_| {
660            NumericLength::FractionDigits
661        }),
662    ))(i)
663}
664
665/// `[31] numericRange ::= "MININCLUSIVE" | "MINEXCLUSIVE" | "MAXINCLUSIVE" | "MAXEXCLUSIVE"`
666fn numeric_range(i: Span) -> IRes<NumericRange> {
667    alt((
668        map(token_tws("MININCLUSIVE"), |_| NumericRange::MinInclusive),
669        map(token_tws("MAXINCLUSIVE"), |_| NumericRange::MaxInclusive),
670        map(token_tws("MINEXCLUSIVE"), |_| NumericRange::MinExclusive),
671        map(token_tws("MAXEXCLUSIVE"), |_| NumericRange::MaxExclusive),
672    ))(i)
673}
674
675/// `[33] shapeDefinition ::= qualifiers '{' tripleExpression? '}' annotation* semanticActions`
676/// qualifiers = (extraPropertySet | "CLOSED" | extends) *
677fn shape_definition<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ShapeExpr> {
678    traced(
679        "shape_definition",
680        map_error(
681            move |i| {
682                let (i, (qualifiers, _, maybe_triple_expr, _, annotations, _, sem_actions)) =
683                    tuple((
684                        qualifiers(),
685                        token_tws("{"),
686                        maybe_triple_expr(),
687                        token_tws("}"),
688                        annotations,
689                        tws0,
690                        semantic_actions,
691                    ))(i)?;
692                let closed = if qualifiers.contains(&Qualifier::Closed) {
693                    Some(true)
694                } else {
695                    None
696                };
697                let mut extra = Vec::new();
698                let mut extends = Vec::new();
699                for q in qualifiers {
700                    match q {
701                        Qualifier::Extends(label) => extends.push(label),
702                        Qualifier::Closed => {}
703                        Qualifier::Extra(ps) => {
704                            for p in ps {
705                                extra.push(p)
706                            }
707                        }
708                    }
709                }
710                let maybe_extra = if extra.is_empty() { None } else { Some(extra) };
711                let maybe_extends = if extends.is_empty() {
712                    None
713                } else {
714                    Some(extends)
715                };
716                let annotations = if annotations.is_empty() {
717                    None
718                } else {
719                    Some(annotations)
720                };
721                Ok((
722                    i,
723                    ShapeExpr::shape(
724                        Shape::new(closed, maybe_extra, maybe_triple_expr)
725                            .with_annotations(annotations)
726                            .with_sem_acts(sem_actions)
727                            .with_extends(maybe_extends),
728                    ),
729                ))
730            },
731            || ShExParseError::ExpectedShapeDefinition,
732        ),
733    )
734}
735
736/// `[34] inlineShapeDefinition ::= qualifiers '{' tripleExpression? '}'`
737fn inline_shape_definition(i: Span) -> IRes<ShapeExpr> {
738    let (i, (qualifiers, _, maybe_triple_expr, _)) = tuple((
739        qualifiers(),
740        token_tws("{"),
741        maybe_triple_expr(),
742        token_tws("}"),
743    ))(i)?;
744    let closed = if qualifiers.contains(&Qualifier::Closed) {
745        Some(true)
746    } else {
747        None
748    };
749    let mut extra = Vec::new();
750    for q in qualifiers {
751        match q {
752            Qualifier::Extends(_) => {
753                todo!()
754            }
755            Qualifier::Closed => {}
756            Qualifier::Extra(ps) => {
757                for p in ps {
758                    extra.push(p)
759                }
760            }
761        }
762    }
763    let maybe_extra = if extra.is_empty() { None } else { Some(extra) };
764    Ok((
765        i,
766        ShapeExpr::shape(Shape::new(closed, maybe_extra, maybe_triple_expr)),
767    ))
768}
769
770fn maybe_triple_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Option<TripleExpr>> {
771    traced("maybe_triple_expr", move |i| {
772        alt((map(triple_expression(), Some), map(tws0, |_| None)))(i)
773    })
774}
775
776fn annotations(i: Span) -> IRes<Vec<Annotation>> {
777    many0(annotation())(i)
778}
779
780fn qualifiers<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Vec<Qualifier>> {
781    traced(
782        "qualifiers",
783        map_error(
784            move |i| many0(qualifier())(i),
785            || ShExParseError::ExpectedQualifiers,
786        ),
787    )
788}
789
790/// `From [34] qualifiers ::= extraPropertySet | "CLOSED" | extension`
791fn qualifier<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Qualifier> {
792    traced(
793        "qualifier",
794        map_error(
795            move |i| alt((extension(), closed(), extra_property_set()))(i),
796            || ShExParseError::ExpectedQualifier,
797        ),
798    )
799}
800
801fn extension<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Qualifier> {
802    traced(
803        "extension",
804        map_error(
805            move |i| {
806                let (i, (_, sr)) = alt((
807                    tuple((tag_no_case_tws("extends"), shape_ref)),
808                    tuple((token_tws("&"), shape_ref)),
809                ))(i)?;
810                Ok((i, Qualifier::Extends(sr)))
811            },
812            || ShExParseError::Extension,
813        ),
814    )
815}
816
817fn closed<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Qualifier> {
818    traced(
819        "Closed",
820        map_error(
821            move |i| {
822                let (i, _) = token_tws("CLOSED")(i)?;
823                Ok((i, Qualifier::Closed))
824            },
825            || ShExParseError::ExpectedClosed,
826        ),
827    )
828}
829
830/// `[35] extraPropertySet ::= "EXTRA" predicate+`
831fn extra_property_set<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Qualifier> {
832    traced(
833        "extra_property_set",
834        map_error(
835            move |i| {
836                let (i, (_, ps)) =
837                    tuple((token_tws("EXTRA"), cut(many1(tuple((predicate, tws0))))))(i)?;
838                let ps = ps.into_iter().map(|(p, _)| p).collect();
839                Ok((i, Qualifier::Extra(ps)))
840            },
841            || ShExParseError::ExpectedEXTRAPropertySet,
842        ),
843    )
844}
845
846/// `[36] tripleExpression ::= oneOfTripleExpr`
847fn triple_expression<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
848    traced(
849        "triple_expression",
850        map_error(
851            move |i| one_of_triple_expr()(i),
852            || ShExParseError::TripleExpression,
853        ),
854    )
855}
856
857/// `[37] oneOfTripleExpr ::= groupTripleExpr | multiElementOneOf`
858fn one_of_triple_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
859    traced(
860        "one_of_triple_expr",
861        map_error(
862            move |i| alt((multi_element_one_of(), group_triple_expr()))(i),
863            || ShExParseError::OneOfTripleExpr,
864        ),
865    )
866}
867
868/// `[38] multiElementOneOf ::= groupTripleExpr ('|' groupTripleExpr)+`
869fn multi_element_one_of<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
870    traced("multi_element_one_of", move |i| {
871        let (i, (te1, _, tes)) = tuple((group_triple_expr(), tws0, rest_group_triple_expr))(i)?;
872        let mut rs = vec![te1];
873        for te in tes {
874            rs.push(te);
875        }
876        let te = TripleExpr::one_of(rs);
877        Ok((i, te))
878    })
879}
880
881/// From [38] rest_group_triple_expr = ('|' groupTripleExpr)+
882fn rest_group_triple_expr(i: Span) -> IRes<Vec<TripleExpr>> {
883    let (i, vs) = many1(tuple((token_tws("|"), group_triple_expr())))(i)?;
884    let mut tes = Vec::new();
885    for v in vs {
886        let (_, te) = v;
887        tes.push(te);
888    }
889    Ok((i, tes))
890}
891
892/// `[40] groupTripleExpr ::= singleElementGroup | multiElementGroup`
893fn group_triple_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
894    traced("group_triple_expr", move |i| {
895        alt((multi_element_group, single_element_group))(i)
896    })
897}
898
899/// `[41] singleElementGroup ::= unaryTripleExpr ';'?`
900fn single_element_group(i: Span) -> IRes<TripleExpr> {
901    let (i, (te, _, _)) = tuple((unary_triple_expr(), tws0, opt(char(';'))))(i)?;
902    Ok((i, te))
903}
904
905/// `[42] multiElementGroup ::= unaryTripleExpr (';' unaryTripleExpr)+ ';'?`
906fn multi_element_group(i: Span) -> IRes<TripleExpr> {
907    let (i, (te1, _, tes, _, _)) = tuple((
908        unary_triple_expr(),
909        tws0,
910        rest_unary_triple_expr,
911        tws0,
912        opt(char(';')),
913    ))(i)?;
914    let mut rs = vec![te1];
915    for t in tes {
916        rs.push(t);
917    }
918    let te = TripleExpr::each_of(rs);
919    Ok((i, te))
920}
921
922/// From [42] rest_unary_triple_expr = (';' unaryTripleExpr)+
923fn rest_unary_triple_expr(i: Span) -> IRes<Vec<TripleExpr>> {
924    let (i, vs) = many1(tuple((token_tws(";"), unary_triple_expr())))(i)?;
925    let mut tes = Vec::new();
926    for v in vs {
927        let (_, te) = v;
928        tes.push(te)
929    }
930    Ok((i, tes))
931}
932
933/// `[43] unaryTripleExpr ::= ('$' tripleExprLabel)? (tripleConstraint | bracketedTripleExpr)`
934/// `                     |   include`
935fn unary_triple_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
936    traced(
937        "unary_triple_expr",
938        map_error(
939            move |i| alt((include_(), unary_triple_expr_opt1))(i),
940            || ShExParseError::UnaryTripleExpr,
941        ),
942    )
943}
944
945/// From [41] unary_triple_expr_opt1 = ('$' tripleExprLabel)? (tripleConstraint | bracketedTripleExpr)
946fn unary_triple_expr_opt1(i: Span) -> IRes<TripleExpr> {
947    let (i, (id, _, te)) = tuple((
948        triple_expr_label_opt,
949        tws0,
950        alt((bracketed_triple_expr(), triple_constraint())),
951    ))(i)?;
952    Ok((i, te.with_id(id)))
953}
954
955// From unary_triple_expr_opt1
956fn triple_expr_label_opt(i: Span) -> IRes<Option<TripleExprLabel>> {
957    let (i, maybe_ts) = opt(tuple((char('$'), tws0, triple_expr_label)))(i)?;
958    let maybe_label = maybe_ts.map(|(_, _, r)| r);
959    Ok((i, maybe_label))
960}
961
962/// `[44] bracketedTripleExpr ::= '(' tripleExpression ')' cardinality? annotation* semanticActions`
963fn bracketed_triple_expr<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
964    traced(
965        "bracketed_triple_expr",
966        map_error(
967            move |i| {
968                let (i, (_, te, _, maybe_card, _, annotations, _, sem_acts)) =
969                    tuple((
970                        token_tws("("),
971                        cut(triple_expression()),
972                        cut(token_tws(")")),
973                        cut(opt(cardinality())),
974                        tws0,
975                        annotations,
976                        tws0,
977                        semantic_actions,
978                    ))(i)?;
979                let mut te = te;
980                if let Some(card) = maybe_card {
981                    te = te.with_min(card.min());
982                    te = te.with_max(card.max());
983                };
984                if !annotations.is_empty() {
985                    te = te.with_annotations(Some(annotations));
986                }
987                te = te.with_sem_acts(sem_acts);
988                Ok((i, te))
989            },
990            || ShExParseError::BracketedTripleExpr,
991        ),
992    )
993}
994
995/// `[45] tripleConstraint ::= senseFlags? predicate inlineShapeExpression cardinality? annotation* semanticActions`
996fn triple_constraint<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
997    traced(
998        "triple_constraint",
999        map_error(
1000            move |i| {
1001                let (
1002                    i,
1003                    (
1004                        maybe_sense_flags,
1005                        _,
1006                        predicate,
1007                        _,
1008                        se,
1009                        _,
1010                        maybe_card,
1011                        _,
1012                        annotations,
1013                        _,
1014                        sem_acts,
1015                    ),
1016                ) = tuple((
1017                    opt(sense_flags),
1018                    tws0,
1019                    predicate,
1020                    tws0,
1021                    inline_shape_expression(),
1022                    tws0,
1023                    opt(cardinality()),
1024                    tws0,
1025                    annotations,
1026                    tws0,
1027                    semantic_actions,
1028                ))(i)?;
1029                let (min, max) = match maybe_card {
1030                    None => (None, None),
1031                    Some(card) => (card.min(), card.max()),
1032                };
1033                let value_expr = if se == ShapeExpr::any() {
1034                    None
1035                } else {
1036                    Some(se)
1037                };
1038                let (negated, inverse) = match maybe_sense_flags {
1039                    Some(sf) => sf.extract(),
1040                    None => (None, None),
1041                };
1042                let mut te = TripleExpr::triple_constraint(
1043                    negated, inverse, predicate, value_expr, min, max,
1044                );
1045                te = te.with_sem_acts(sem_acts);
1046                if !annotations.is_empty() {
1047                    te = te.with_annotations(Some(annotations))
1048                }
1049                Ok((i, te))
1050            },
1051            || ShExParseError::ExpectedTripleConstraint,
1052        ),
1053    )
1054}
1055
1056fn sense_flags(i: Span) -> IRes<SenseFlags> {
1057    alt((sense_flags_negated, sense_flags_inverse))(i)
1058}
1059
1060fn negated(i: Span) -> IRes<Span> {
1061    token_tws("!")(i)
1062}
1063
1064fn inverse(i: Span) -> IRes<Span> {
1065    token_tws("^")(i)
1066}
1067
1068fn sense_flags_negated(i: Span) -> IRes<SenseFlags> {
1069    let (i, (_, maybe_inverse)) = tuple((negated, opt(inverse)))(i)?;
1070    let inverse = maybe_inverse.map(|_| true);
1071    Ok((
1072        i,
1073        SenseFlags {
1074            negated: Some(true),
1075            inverse,
1076        },
1077    ))
1078}
1079
1080fn sense_flags_inverse(i: Span) -> IRes<SenseFlags> {
1081    let (i, (_, maybe_negated)) = tuple((inverse, opt(negated)))(i)?;
1082    let negated = maybe_negated.map(|_| true);
1083    Ok((
1084        i,
1085        SenseFlags {
1086            inverse: Some(true),
1087            negated,
1088        },
1089    ))
1090}
1091
1092/// `[46] cardinality ::= '*' | '+' | '?' | REPEAT_RANGE`
1093fn cardinality<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Cardinality> {
1094    traced(
1095        "cardinality",
1096        map_error(
1097            move |i| alt((plus, star, optional, repeat_range()))(i),
1098            || ShExParseError::ExpectedCardinality,
1099        ),
1100    )
1101}
1102
1103fn plus(i: Span) -> IRes<Cardinality> {
1104    let (i, _) = char('+')(i)?;
1105    Ok((i, Cardinality::plus()))
1106}
1107
1108fn star(i: Span) -> IRes<Cardinality> {
1109    let (i, _) = char('*')(i)?;
1110    Ok((i, Cardinality::star()))
1111}
1112
1113fn optional(i: Span) -> IRes<Cardinality> {
1114    let (i, _) = char('?')(i)?;
1115    Ok((i, Cardinality::optional()))
1116}
1117
1118/// `[48] valueSet ::= '[' valueSetValue* ']'`
1119fn value_set<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NodeConstraint> {
1120    traced(
1121        "value set",
1122        map_error(
1123            move |i| {
1124                let (i, (_, vs, _)) =
1125                    tuple((token_tws("["), many0(value_set_value()), token_tws("]")))(i)?;
1126                Ok((i, NodeConstraint::new().with_values(vs)))
1127            },
1128            || ShExParseError::ValueSet,
1129        ),
1130    )
1131}
1132
1133/// `[49] valueSetValue ::= iriRange | literalRange | languageRange`
1134/// `                       | exclusion+`
1135fn value_set_value<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1136    traced(
1137        "value_set_value",
1138        map_error(
1139            move |i| {
1140                alt((
1141                    exclusion_plus(),
1142                    iri_range,
1143                    literal_range(),
1144                    language_range(),
1145                ))(i)
1146            },
1147            || ShExParseError::ValueSetValue,
1148        ),
1149    )
1150}
1151
1152/// exclusion+ changed by: '.' (iriExclusion+ | literalExclusion+ | languageExclusion+)
1153fn exclusion_plus<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1154    traced(
1155        "wildcard exclusion",
1156        map_error(
1157            move |i| {
1158                let (i, (_, e)) = tuple((
1159                    token_tws("."),
1160                    alt((
1161                        map(many1(literal_exclusion), |es| {
1162                            ValueSetValue::LiteralStemRange {
1163                                stem: StringOrWildcard::Wildcard,
1164                                exclusions: Some(es),
1165                            }
1166                        }),
1167                        map(many1(language_exclusion), |es| {
1168                            ValueSetValue::LanguageStemRange {
1169                                stem: LangOrWildcard::Wildcard,
1170                                exclusions: Some(es),
1171                            }
1172                        }),
1173                        map(many1(iri_exclusion), |es| ValueSetValue::IriStemRange {
1174                            stem: IriRefOrWildcard::Wildcard,
1175                            exclusions: Some(es),
1176                        }),
1177                    )),
1178                ))(i)?;
1179                Ok((i, e))
1180            },
1181            || ShExParseError::ExclusionPlus,
1182        ),
1183    )
1184}
1185
1186/// `[51] iriRange ::= iri ('~' exclusion*)?`
1187fn iri_range(i: Span) -> IRes<ValueSetValue> {
1188    let (i, (iri, _, maybe_stem)) = tuple((iri, tws0, opt(tilde_iri_exclusion)))(i)?;
1189    let value = match maybe_stem {
1190        None => ValueSetValue::iri(iri),
1191        Some(excs) => {
1192            if excs.is_empty() {
1193                ValueSetValue::IriStem { stem: iri }
1194            } else {
1195                ValueSetValue::IriStemRange {
1196                    stem: IriRefOrWildcard::IriRef(iri),
1197                    exclusions: Some(excs),
1198                }
1199            }
1200        }
1201    };
1202    Ok((i, value))
1203}
1204
1205fn tilde_iri_exclusion(i: Span) -> IRes<Vec<IriExclusion>> {
1206    let (i, (_, _, es)) = tuple((char('~'), tws0, many0(iri_exclusion)))(i)?;
1207    Ok((i, es))
1208}
1209
1210fn tilde_literal_exclusion(i: Span) -> IRes<Vec<LiteralExclusion>> {
1211    let (i, (_, es)) = tuple((token_tws("~"), many0(literal_exclusion)))(i)?;
1212    Ok((i, es))
1213}
1214
1215/// `[52] exclusion ::= '-' (iri | literal | LANGTAG) '~'?`
1216fn iri_exclusion(i: Span) -> IRes<IriExclusion> {
1217    let (i, (_, iri, _, maybe_tilde)) = tuple((token_tws("-"), iri, tws0, opt(token_tws("~"))))(i)?;
1218    let iri_exc = match maybe_tilde {
1219        None => IriExclusion::Iri(iri),
1220        Some(_) => IriExclusion::IriStem(iri),
1221    };
1222    Ok((i, iri_exc))
1223}
1224
1225/// `[53] literalRange ::= literal ('~' literalExclusion*)?`
1226fn literal_range<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1227    traced(
1228        "literal_range",
1229        map_error(
1230            move |i| {
1231                let (i, (literal, _, maybe_exc)) =
1232                    tuple((literal(), tws0, opt(tilde_literal_exclusion)))(i)?;
1233                let vs = match maybe_exc {
1234                    None => ValueSetValue::ObjectValue(ObjectValue::Literal(literal)),
1235                    Some(excs) => {
1236                        if excs.is_empty() {
1237                            ValueSetValue::literal_stem(literal.lexical_form())
1238                        } else {
1239                            ValueSetValue::string_stem_range(literal.lexical_form(), excs)
1240                        }
1241                    }
1242                };
1243                Ok((i, vs))
1244            },
1245            || ShExParseError::ExpectedLiteralRange,
1246        ),
1247    )
1248}
1249
1250/*fn tilde_literal_exclusion<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Vec<Exclusion>> {
1251  move |i| {
1252    let (i, (_, es)) = tuple((tilde(), many0(literal_exclusion)))(i)?;
1253    Ok((i, es))
1254  }
1255}*/
1256
1257fn tilde<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Span<'a>> {
1258    move |i| token_tws("~")(i)
1259}
1260
1261fn dash<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Span<'a>> {
1262    move |i| token_tws("-")(i)
1263}
1264
1265/// `[54] literalExclusion ::= '-' literal '~'?`
1266fn literal_exclusion(i: Span) -> IRes<LiteralExclusion> {
1267    let (i, (_, literal, maybe_tilde)) = tuple((dash(), literal(), opt(tilde())))(i)?;
1268    let le = match maybe_tilde {
1269        Some(_) => LiteralExclusion::LiteralStem(literal.lexical_form()),
1270        None => LiteralExclusion::Literal(literal.lexical_form()),
1271    };
1272    Ok((i, le))
1273}
1274
1275/// `[55] languageRange ::= LANGTAG ('~' languageExclusion*)?`
1276/// `                     | '@' '~' languageExclusion*`
1277fn language_range<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1278    traced(
1279        "language_range",
1280        map_error(
1281            move |i| alt((language_range1(), language_range2()))(i),
1282            || ShExParseError::LanguageRange,
1283        ),
1284    )
1285}
1286
1287/// `From [55] languageRange1 = LANGTAG ('~' languageExclusion*)?`
1288fn language_range1<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1289    traced(
1290        "language_range1",
1291        map_error(
1292            move |i| {
1293                let (i, (lang_tag, _, maybe_stem_exclusions)) = tuple((
1294                    lang_tag,
1295                    tws0,
1296                    opt(tuple((token_tws("~"), language_exclusions))),
1297                ))(i)?;
1298                let value: ValueSetValue = match maybe_stem_exclusions {
1299                    None => ValueSetValue::language(lang_tag),
1300                    Some((_, exclusions)) => {
1301                        if exclusions.is_empty() {
1302                            ValueSetValue::language_stem(lang_tag)
1303                        } else {
1304                            ValueSetValue::LanguageStemRange {
1305                                stem: LangOrWildcard::Lang(lang_tag),
1306                                exclusions: Some(exclusions),
1307                            }
1308                        }
1309                    }
1310                };
1311                Ok((i, value))
1312            },
1313            || ShExParseError::LanguageRange,
1314        ),
1315    )
1316}
1317
1318/// `From [55] languageRange1 = '@' '~' languageExclusion*`
1319fn language_range2<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ValueSetValue> {
1320    traced(
1321        "language_range2",
1322        map_error(
1323            move |i| {
1324                let (i, (_, _, exclusions)) =
1325                    tuple((token_tws("@"), token_tws("~"), language_exclusions))(i)?;
1326                let v = if exclusions.is_empty() {
1327                    ValueSetValue::LanguageStem {
1328                        // TODO: why is this empty?
1329                        stem: Lang::new_unchecked(""),
1330                    }
1331                } else {
1332                    ValueSetValue::LanguageStemRange {
1333                        stem: LangOrWildcard::Lang(Lang::new_unchecked("")),
1334                        exclusions: Some(exclusions),
1335                    }
1336                };
1337                Ok((i, v))
1338            },
1339            || ShExParseError::LanguageRange,
1340        ),
1341    )
1342}
1343
1344/// `from [55] language_exclusions = languageExclusion*`
1345fn language_exclusions(i: Span) -> IRes<Vec<LanguageExclusion>> {
1346    many0(language_exclusion)(i)
1347}
1348
1349/// `[56] languageExclusion ::= '-' LANGTAG '~'?`
1350fn language_exclusion(i: Span) -> IRes<LanguageExclusion> {
1351    let (i, (_, lang, _, maybe_tilde)) =
1352        tuple((token_tws("-"), lang_tag, tws0, opt(token_tws("~"))))(i)?;
1353    let lang_exc = match maybe_tilde {
1354        None => LanguageExclusion::Language(lang),
1355        Some(_) => LanguageExclusion::LanguageStem(lang),
1356    };
1357    Ok((i, lang_exc))
1358}
1359
1360/// `[57] include ::= '&' tripleExprLabel`
1361fn include_<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, TripleExpr> {
1362    traced(
1363        "include",
1364        map_error(
1365            move |i| {
1366                let (i, (_, tel)) = tuple((token_tws("&"), cut(triple_expr_label)))(i)?;
1367                Ok((i, TripleExpr::TripleExprRef(tel)))
1368            },
1369            || ShExParseError::Include,
1370        ),
1371    )
1372}
1373
1374/// `[58] annotation ::= "//" predicate (iri | literal)`
1375fn annotation<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Annotation> {
1376    traced(
1377        "annotation",
1378        map_error(
1379            move |i| {
1380                let (i, (_, p, _, o)) =
1381                    tuple((token_tws("//"), cut(predicate), tws0, cut(iri_or_literal())))(i)?;
1382                Ok((i, Annotation::new(p, o)))
1383            },
1384            || ShExParseError::ExpectedAnnotation,
1385        ),
1386    )
1387}
1388
1389/// From [58] iri_or_literal = (iri | literal)
1390fn iri_or_literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, ObjectValue> {
1391    traced(
1392        "iri_or_literal",
1393        map_error(
1394            move |i| {
1395                alt((
1396                    map(iri, ObjectValue::iri_ref),
1397                    map(literal(), ObjectValue::Literal),
1398                ))(i)
1399            },
1400            || ShExParseError::ExpectedIriOrLiteral,
1401        ),
1402    )
1403}
1404
1405/// `[59] semanticActions ::= codeDecl*`
1406fn semantic_actions(i: Span) -> IRes<Option<Vec<SemAct>>> {
1407    let (i, sas) = many0(code_decl())(i)?;
1408    if sas.is_empty() {
1409        Ok((i, None))
1410    } else {
1411        Ok((i, Some(sas)))
1412    }
1413}
1414
1415/// `[60] codeDecl ::= '%' iri (CODE | '%')`
1416fn code_decl<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, SemAct> {
1417    traced(
1418        "code_decl",
1419        map_error(
1420            move |i| {
1421                let (i, (_, _, iri, _, code, _)) =
1422                    tuple((char('%'), tws0, cut(iri), tws0, cut(code_or_percent), tws0))(i)?;
1423                Ok((i, SemAct::new(iri, code)))
1424            },
1425            || ShExParseError::CodeDeclaration,
1426        ),
1427    )
1428}
1429
1430fn code_or_percent(i: Span) -> IRes<Option<String>> {
1431    let (i, maybe_code) = alt((code(), percent_code))(i)?;
1432    Ok((i, maybe_code))
1433}
1434
1435fn percent_code(i: Span) -> IRes<Option<String>> {
1436    let (i, _) = char('%')(i)?;
1437    Ok((i, None))
1438}
1439
1440/// `[13t] literal ::= rdfLiteral | numericLiteral | booleanLiteral`
1441pub fn literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Literal> {
1442    traced(
1443        "literal",
1444        map_error(
1445            move |i| {
1446                alt((
1447                    rdf_literal(),
1448                    map(numeric_literal, Literal::NumericLiteral),
1449                    boolean_literal,
1450                ))(i)
1451            },
1452            || ShExParseError::Literal,
1453        ),
1454    )
1455}
1456
1457/// `[16t] numericLiteral ::= INTEGER | DECIMAL | DOUBLE`
1458fn numeric_literal(i: Span) -> IRes<NumericLiteral> {
1459    alt((
1460        map(double, NumericLiteral::double),
1461        decimal,
1462        integer_literal(),
1463    ))(i)
1464}
1465
1466/// raw_numeric_literal obtains a numeric literal as a JSON
1467/// `[16t] rawnumericLiteral ::= INTEGER | DECIMAL | DOUBLE
1468/// `
1469fn raw_numeric_literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NumericLiteral> {
1470    map_error(
1471        move |i| {
1472            alt((
1473                map(double, NumericLiteral::decimal_from_f64),
1474                decimal,
1475                raw_integer_literal(),
1476            ))(i)
1477        },
1478        || ShExParseError::NumericLiteral,
1479    )
1480}
1481
1482fn raw_integer_literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NumericLiteral> {
1483    map_error(
1484        move |i| map(integer(), NumericLiteral::decimal_from_i128)(i),
1485        || ShExParseError::IntegerLiteral,
1486    )
1487}
1488
1489fn integer_literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, NumericLiteral> {
1490    map_error(
1491        move |i| map(integer(), NumericLiteral::integer_from_i128)(i),
1492        || ShExParseError::IntegerLiteral,
1493    )
1494}
1495
1496fn boolean_literal(i: Span) -> IRes<Literal> {
1497    map(boolean_value, Literal::boolean)(i)
1498}
1499
1500fn boolean_value(i: Span) -> IRes<bool> {
1501    alt((
1502        map(token_tws("true"), |_| true),
1503        map(token_tws("false"), |_| false),
1504    ))(i)
1505}
1506
1507/// `[65] rdfLiteral ::= langString | string ("^^" datatype)?`
1508/// Refactored according to rdfLiteral in Turtle
1509/// `rdfLiteral ::= string (LANGTAG | '^^' iri)?`
1510fn rdf_literal<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Literal> {
1511    traced(
1512        "rdf_literal",
1513        map_error(
1514            move |i| {
1515                let (i, str) = string()(i)?;
1516                let (i, maybe_value) = opt(alt((
1517                    map(lang_tag, |lang| Literal::lang_str(&str, lang)),
1518                    map(preceded(token("^^"), datatype_iri), |datatype| {
1519                        Literal::lit_datatype(&str, &datatype)
1520                    }),
1521                )))(i)?;
1522                let value = match maybe_value {
1523                    Some(v) => v,
1524                    None => Literal::str(&str),
1525                };
1526                Ok((i, value))
1527            },
1528            || ShExParseError::RDFLiteral,
1529        ),
1530    )
1531}
1532
1533/// ``
1534fn datatype_iri(i: Span) -> IRes<IriRef> {
1535    iri(i)
1536}
1537
1538/// `[135s] string ::= STRING_LITERAL1 | STRING_LITERAL_LONG1`
1539/// `                  | STRING_LITERAL2 | STRING_LITERAL_LONG2`
1540fn string<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, String> {
1541    traced(
1542        "string",
1543        map_error(
1544            move |i| {
1545                alt((
1546                    string_literal_long1,
1547                    string_literal_long2,
1548                    string_literal1(),
1549                    string_literal2,
1550                ))(i)
1551            },
1552            || ShExParseError::ExpectedStringLiteral,
1553        ),
1554    )
1555}
1556
1557fn string_literal2(i: Span) -> IRes<String> {
1558    let (i, chars) = delimited(
1559        token(r#"""#),
1560        cut(many0(alt((none_of(REQUIRES_ESCAPE), echar, uchar)))),
1561        token(r#"""#),
1562    )(i)?;
1563    let str = chars.iter().collect();
1564    Ok((i, str))
1565}
1566
1567/// `[156s] <STRING_LITERAL1> ::= "'" ([^'\\\n\r] | ECHAR | UCHAR)* "'"`
1568fn string_literal1<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, String> {
1569    traced(
1570        "string_literal1",
1571        map_error(
1572            move |i| {
1573                let (i, chars) = delimited(
1574                    token("'"),
1575                    many0(alt((single_quote_char(), echar, uchar))),
1576                    token("'"),
1577                )(i)?;
1578                let str = chars.iter().collect();
1579                Ok((i, str))
1580            },
1581            || ShExParseError::StringLiteralQuote,
1582        ),
1583    )
1584}
1585
1586fn single_quote_char<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, char> {
1587    traced("single_quote_char", move |i| {
1588        none_of(REQUIRES_ESCAPE_SINGLE_QUOTE)(i)
1589    })
1590}
1591
1592/// `[158s] <STRING_LITERAL_LONG1> ::= "'''" ( ("'" | "''")? ([^\\'\\] | ECHAR | UCHAR) )* "'''"`
1593fn string_literal_long1(i: Span) -> IRes<String> {
1594    let (i, chars) = delimited(
1595        token("'''"),
1596        cut(many0(alt((none_of(r"'\"), echar, uchar)))),
1597        token("'''"),
1598    )(i)?;
1599    let str = chars.iter().collect();
1600    Ok((i, str))
1601}
1602
1603/// `[159s] <STRING_LITERAL_LONG2> ::= '"""' ( ('"' | '""')? ([^\"\\] | ECHAR | UCHAR) )* '"""'`
1604fn string_literal_long2(i: Span) -> IRes<String> {
1605    let (i, chars) = delimited(
1606        token(r#"""""#),
1607        cut(many0(alt((none_of(r#""\"#), echar, uchar)))),
1608        token(r#"""""#),
1609    )(i)?;
1610    let str = chars.iter().collect();
1611    Ok((i, str))
1612}
1613
1614pub fn hex(input: Span) -> IRes<Span> {
1615    recognize(one_of(HEXDIGIT))(input)
1616}
1617
1618pub static HEX: &Lazy<Regex> = regex!("[0123456789ABCDEFabcdef]");
1619
1620pub fn hex_refactor(input: Span) -> IRes<Span> {
1621    re_find(HEX)(input)
1622}
1623
1624use nom::Slice;
1625pub fn re_find<'a>(re: &'a Lazy<Regex>) -> impl Fn(Span<'a>) -> IRes<'a, Span<'a>> {
1626    move |i| {
1627        let str = i.fragment();
1628        if let Some(m) = re.find(str) {
1629            Ok((i.slice(m.end()..), i.slice(m.start()..m.end())))
1630        } else {
1631            let e = ShExParseError::RegexFailed {
1632                re: re.to_string(),
1633                str: str.to_string(),
1634            };
1635            Err(Err::Error(e.at(i)))
1636        }
1637    }
1638}
1639
1640/// Valid hexadecimal digits.
1641const HEXDIGIT: &str = "0123456789ABCDEFabcdef";
1642
1643/// Characters requiring escape sequences in single-line string literals.
1644/// 22 = ", 5C = \, 0A = \n, 0D = \r
1645const REQUIRES_ESCAPE: &str = "\u{22}\u{5C}\u{0A}\u{0D}";
1646
1647/// Characters requiring escape sequences in single-line string literals.
1648/// 22 = ", 5C = \, 0A = \n, 0D = \r
1649const REQUIRES_ESCAPE_SINGLE_QUOTE: &str = "\u{27}\u{5C}\u{0A}\u{0D}";
1650
1651/// `[26t] <UCHAR> ::= "\\u" HEX HEX HEX HEX`
1652/// `          | "\\U" HEX HEX HEX HEX HEX HEX HEX HEX`
1653fn uchar(i: Span) -> IRes<char> {
1654    let (i, str) = recognize(alt((
1655        preceded(token(r"\u"), count(hex, 4)),
1656        preceded(token(r"\U"), count(hex, 8)),
1657    )))(i)?;
1658    let c = unescape_uchar(str.fragment()).unwrap();
1659    Ok((i, c))
1660}
1661
1662/// `[160s] <ECHAR> ::= "\\" [tbnrf\\\"\\']`
1663/// Escaped chars. The unicode chars come from Turtle https://www.w3.org/TR/turtle/#string
1664fn echar(i: Span) -> IRes<char> {
1665    let (i, c) = preceded(token(r"\"), one_of(r#"tbnrf"'\"#))(i)?;
1666    let c = match c {
1667        't' => '\t',
1668        'b' => '\u{0008}',
1669        'n' => '\n',
1670        'r' => '\u{000D}',
1671        'f' => '\u{000C}',
1672        '\"' => '\u{0022}',
1673        '\'' => '\u{0027}',
1674        '\\' => '\u{005C}',
1675        _ => panic!("echar: unrecognized character: {c}"),
1676    };
1677    Ok((i, c))
1678}
1679
1680/// `[145s] <LANGTAG> ::= "@" ([a-zA-Z])+ ("-" ([a-zA-Z0-9])+)*`
1681fn lang_tag(i: Span) -> IRes<Lang> {
1682    let (i, lang_str) = preceded(
1683        token("@"),
1684        recognize(tuple((alpha1, many0(preceded(token("-"), alphanumeric1))))),
1685    )(i)?;
1686    Ok((i, Lang::new_unchecked(*lang_str.fragment())))
1687}
1688
1689/// `[61] predicate ::= iri | RDF_TYPE`
1690fn predicate(i: Span) -> IRes<IriRef> {
1691    alt((iri, rdf_type))(i)
1692}
1693
1694/// `[62] datatype ::= iri`
1695fn datatype(i: Span) -> IRes<NodeConstraint> {
1696    let (i, iri_ref) = iri(i)?;
1697    Ok((i, NodeConstraint::new().with_datatype(iri_ref)))
1698}
1699
1700/// `[63] shapeExprLabel ::= iri | blankNode`
1701pub(crate) fn shape_expr_label(i: Span) -> IRes<ShapeExprLabel> {
1702    let (i, ref_) = alt((iri_as_ref, blank_node_ref))(i)?;
1703    Ok((i, ref_))
1704}
1705fn iri_as_ref(i: Span) -> IRes<ShapeExprLabel> {
1706    let (i, iri_ref) = iri(i)?;
1707    Ok((i, ShapeExprLabel::iri_ref(iri_ref)))
1708}
1709
1710fn blank_node_ref(i: Span) -> IRes<ShapeExprLabel> {
1711    let (i, bn) = blank_node(i)?;
1712    Ok((i, ShapeExprLabel::bnode(bn)))
1713}
1714
1715/// `[64] tripleExprLabel ::= iri | blankNode`
1716fn triple_expr_label(i: Span) -> IRes<TripleExprLabel> {
1717    alt((
1718        map(iri, |value| TripleExprLabel::IriRef { value }),
1719        map(blank_node, |value| TripleExprLabel::BNode { value }),
1720    ))(i)
1721}
1722
1723/// `[67] <CODE> ::= "{" ([^%\\] | "\\" [%\\] | UCHAR)* "%" "}"`
1724/// `     code_str = ([^%\\] | "\\" [%\\] | UCHAR)*`
1725fn code<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Option<String>> {
1726    traced(
1727        "code",
1728        map_error(
1729            move |i| {
1730                let (i, (_, str, _, _, _)) = tuple((
1731                    char('{'),
1732                    cut(code_str),
1733                    cut(char('%')),
1734                    tws0,
1735                    cut(char('}')),
1736                ))(i)?;
1737                // let str = unescape_code(str.fragment());
1738                Ok((i, Some(str)))
1739            },
1740            || ShExParseError::Code,
1741        ),
1742    )
1743}
1744
1745/*fn unescape_code(str: &str) -> String {
1746    let non_escaped = ['%', '\\'];
1747    let mut queue : VecDeque<_> = str.chars().collect();
1748    let mut r = String::new();
1749    while let Some(c) = queue.pop_front() {
1750        if c != '\\' {
1751            r.push(c);
1752            continue;
1753        }
1754        match queue.pop_front() {
1755            Some(c) if non_escaped.contains(&c) => {
1756                r.push('\\');
1757                r.push(c)
1758            }
1759            Some('u') => {
1760                let mut s = String::new();
1761                for _ in 0..4 {
1762                    if let Some(c) = queue.pop_front() {
1763                       s.push(c)
1764                    } else {
1765                        panic!("unescape_code: \\u is not followed by 4 chars")
1766                    }
1767                }
1768
1769                let u = u32::from_str_radix(&s, 16).unwrap();
1770                let c = char::from_u32(u).unwrap();
1771                r.push(c)
1772            }
1773            Some('U') => {
1774                let mut s = String::new();
1775                for _ in 0..8 {
1776                    if let Some(c) = queue.pop_front() {
1777                       s.push(c)
1778                    } else {
1779                        panic!("unescape_code: \\u is not followed by 8 chars")
1780                    }
1781                }
1782
1783                let u = u32::from_str_radix(&s, 16).unwrap();
1784                let c = char::from_u32(u).unwrap();
1785                r.push(c)
1786            }
1787            Some(c) => r.push(c),
1788            None => panic!("unescape pattern. No more characters after \\")
1789        }
1790    }
1791    r
1792}*/
1793
1794/// from [67] code_str = ([^%\\] | "\\" [%\\] | UCHAR)*
1795fn code_str(i: Span) -> IRes<String> {
1796    let (i, chars) = many0(alt((none_of(REQUIRES_ESCAPE_CODE), escaped_code, uchar)))(i)?;
1797    let str = chars.iter().collect();
1798    Ok((i, str))
1799}
1800
1801/// Characters requiring escape sequences in patterns
1802/// %, 5C = \
1803const REQUIRES_ESCAPE_CODE: &str = "%\u{5C}";
1804
1805/// from [67] escaped_code = "\\" [%\\]
1806fn escaped_code(i: Span) -> IRes<char> {
1807    let (i, c) = preceded(token(r"\"), one_of(r#"%\"#))(i)?;
1808    Ok((i, c))
1809}
1810
1811/// `[68] <REPEAT_RANGE> ::= "{" INTEGER ( "," (INTEGER | "*")? )? "}"`
1812fn repeat_range<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Cardinality> {
1813    traced(
1814        "repeat_range",
1815        map_error(
1816            move |i| {
1817                let (i, (_, min, maybe_rest_range, _)) =
1818                    tuple((token("{"), integer(), opt(rest_range()), cut(token("}"))))(i)?;
1819                let cardinality = match maybe_rest_range {
1820                    None => Cardinality::exact(min as i32),
1821                    Some(maybe_max) => match maybe_max {
1822                        None => Cardinality::min_max(min as i32, -1),
1823                        Some(max) => Cardinality::min_max(min as i32, max),
1824                    },
1825                };
1826                Ok((i, cardinality))
1827            },
1828            || ShExParseError::ExpectedRepeatRange,
1829        ),
1830    )
1831}
1832
1833/// From [68] rest_range = "," (INTEGER | "*")?
1834/// rest_range = "," integer_or_star ?
1835fn rest_range<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, Option<i32>> {
1836    traced(
1837        "rest_range",
1838        map_error(
1839            move |i| {
1840                let (i, (_, maybe_max)) = tuple((token_tws(","), opt(integer_or_star)))(i)?;
1841                Ok((i, maybe_max))
1842            },
1843            || ShExParseError::ExpectedRestRepeatRange,
1844        ),
1845    )
1846}
1847
1848/// From rest_range, integer_or_star = INTEGER | "*"
1849fn integer_or_star(i: Span) -> IRes<i32> {
1850    alt((
1851        map(integer(), |n| n as i32),
1852        (map(token_tws("*"), |_| (-1))),
1853    ))(i)
1854}
1855
1856/// `[69] <RDF_TYPE> ::= "a"`
1857fn rdf_type(i: Span) -> IRes<IriRef> {
1858    let (i, _) = tag_no_case("a")(i)?;
1859    let rdf_type: IriRef = IriRef::iri(IriS::new_unchecked(RDF_TYPE_STR));
1860    Ok((i, rdf_type))
1861}
1862
1863/// `[70] <ATPNAME_NS> ::= "@" PNAME_NS`
1864fn at_pname_ns(i: Span) -> IRes<ShapeExprLabel> {
1865    let (i, (_, _, pname)) = tuple((char('@'), tws0, pname_ns_iri_ref))(i)?;
1866    let label = ShapeExprLabel::iri_ref(pname);
1867    Ok((i, label))
1868}
1869
1870/// `[71] <ATPNAME_LN> ::= "@" PNAME_LN`
1871fn at_pname_ln(i: Span) -> IRes<ShapeExprLabel> {
1872    let (i, (_, _, pname_ln)) = tuple((char('@'), tws0, pname_ln))(i)?;
1873    Ok((i, ShapeExprLabel::iri_ref(pname_ln)))
1874}
1875
1876/// `[72] <REGEXP> ::= '/' ([^/\\\n\r]
1877/// | '\\' [nrt\\|.?*+(){}$-\[\]^/]
1878/// | UCHAR
1879/// )+ '/' [smix]*`
1880fn regexp(i: Span) -> IRes<Pattern> {
1881    let (i, (_, str, _, flags)) = tuple((char('/'), pattern, cut(char('/')), flags))(i)?;
1882    let flags = flags.fragment();
1883    let flags = if flags.is_empty() {
1884        None
1885    } else {
1886        Some(flags.to_string())
1887    };
1888    let str = unescape_pattern(&str);
1889    Ok((i, Pattern { str, flags }))
1890}
1891
1892/// unescape characters in pattern strings
1893fn unescape_pattern(str: &str) -> String {
1894    let non_escaped = [
1895        'n', 'r', 't', '\\', '|', '.', '?', '*', '+', '(', ')', '{', '}', '$', '-', '[', ']', '^',
1896    ];
1897    let mut queue: VecDeque<_> = str.chars().collect();
1898    let mut r = String::new();
1899    while let Some(c) = queue.pop_front() {
1900        if c != '\\' {
1901            r.push(c);
1902            continue;
1903        }
1904        match queue.pop_front() {
1905            Some(c) if non_escaped.contains(&c) => {
1906                r.push('\\');
1907                r.push(c)
1908            }
1909            Some('u') => {
1910                let mut s = String::new();
1911                for _ in 0..4 {
1912                    if let Some(c) = queue.pop_front() {
1913                        s.push(c)
1914                    } else {
1915                        panic!("unescape_pattern: \\u is not followed by 4 chars")
1916                    }
1917                }
1918
1919                let u = u32::from_str_radix(&s, 16).unwrap();
1920                let c = char::from_u32(u).unwrap();
1921                r.push(c)
1922            }
1923            Some('U') => {
1924                let mut s = String::new();
1925                for _ in 0..8 {
1926                    if let Some(c) = queue.pop_front() {
1927                        s.push(c)
1928                    } else {
1929                        panic!("unescape_pattern: \\u is not followed by 8 chars")
1930                    }
1931                }
1932
1933                let u = u32::from_str_radix(&s, 16).unwrap();
1934                let c = char::from_u32(u).unwrap();
1935                r.push(c)
1936            }
1937            Some(c) => r.push(c),
1938            None => panic!("unescape pattern. No more characters after \\"),
1939        }
1940    }
1941    r
1942}
1943
1944/// [72b] from [72] pattern = ([^/\\\n\r] | '\\' [nrt\\|.?*+(){}$-\[\]^/] | UCHAR) +
1945fn pattern(i: Span) -> IRes<String> {
1946    let (i, chars) = many1(alt((
1947        map(none_of(REQUIRES_ESCAPE_PATTERN), |c| vec![c]),
1948        escaped_pattern,
1949        map(uchar, |c| vec![c]),
1950    )))(i)?;
1951    let str = chars.iter().flatten().collect();
1952    Ok((i, str))
1953}
1954
1955/// from [72b] escaped_pattern = '\\' [nrt\\|.?*+(){}$-\[\]^/]
1956fn escaped_pattern(i: Span) -> IRes<Vec<char>> {
1957    let (i, c) = preceded(token(r"\"), one_of(r#"nrt\|.?*+(){}$-[]^/"#))(i)?;
1958    Ok((i, vec!['\\', c]))
1959}
1960
1961/// Characters requiring escape sequences in patterns
1962/// 2F = /, 5C = \, 0A = \n, 0D = \r
1963const REQUIRES_ESCAPE_PATTERN: &str = "\u{2F}\u{5C}\u{0A}\u{0D}";
1964
1965/// `from [72] flags = [smix]*`
1966fn flags(i: Span) -> IRes<Span> {
1967    recognize(many0(alt((char('s'), char('m'), char('i'), char('x')))))(i)
1968}
1969
1970/// `[136s] iri ::= IRIREF | prefixedName`
1971pub(crate) fn iri(i: Span) -> IRes<IriRef> {
1972    alt((iri_ref_s, prefixed_name()))(i)
1973}
1974
1975fn iri_ref_s(i: Span) -> IRes<IriRef> {
1976    let (i, iri) = iri_ref(i)?;
1977    Ok((i, iri.into()))
1978}
1979
1980/// `[137s] prefixedName ::= PNAME_LN | PNAME_NS`
1981fn prefixed_name<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, IriRef> {
1982    traced(
1983        "prefixed_name",
1984        map_error(
1985            move |i| {
1986                let (i, iri_ref) = alt((pname_ln, pname_ns_iri_ref))(i)?;
1987                Ok((i, iri_ref))
1988            },
1989            || ShExParseError::ExpectedPrefixedName,
1990        ),
1991    )
1992}
1993
1994/*
1995/// `[137s]   	prefixedName	   ::=   	PNAME_LN | PNAME_NS`
1996fn prefixed_name_refactor<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, IriRef> {
1997    traced(
1998        "prefixed_name",
1999        map_error(
2000            move |i| {
2001                let (i, iri_ref) = alt((pname_ln, pname_ns_iri_ref))(i)?;
2002                Ok((i, iri_ref))
2003            },
2004            || ShExParseError::ExpectedPrefixedName,
2005        ),
2006    )
2007}
2008*/
2009
2010fn pname_ns_iri_ref(i: Span) -> IRes<IriRef> {
2011    let (i, pname_ns) = pname_ns(i)?;
2012    Ok((i, IriRef::prefixed(pname_ns.fragment(), "")))
2013}
2014
2015/// `[138s] blankNode ::= BLANK_NODE_LABEL`
2016fn blank_node(i: Span) -> IRes<BNode> {
2017    map(blank_node_label, BNode::new)(i)
2018}
2019
2020//----   Terminals
2021
2022/// `[142s] <BLANK_NODE_LABEL> ::= "_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)?`
2023fn blank_node_label(i: Span) -> IRes<&str> {
2024    let (i, _) = tag("_:")(i)?;
2025    let (i, label) = recognize(tuple((one_if(is_pn_chars_u_digit), blank_node_label2)))(i)?;
2026    Ok((i, label.fragment()))
2027}
2028
2029fn is_pn_chars_u_digit(c: char) -> bool {
2030    is_digit(c) || is_pn_chars_u(c)
2031}
2032
2033fn is_pn_chars_or_dot(c: char) -> bool {
2034    c == '.' || is_pn_chars(c)
2035}
2036
2037fn blank_node_label2(src: Span) -> IRes<()> {
2038    match blank_node_label3(src) {
2039        Ok((left, m)) => {
2040            // if last is a '.', remove that
2041            if m.ends_with('.') {
2042                // TODO!!: Original parser had this:
2043                // But I need to see how to remove the last character of left...
2044                // Ok(((&src[m.len() - 1..]), ()))
2045                tracing::error!("This code is pending review when the last is a '.' {left}");
2046                Ok((left, ()))
2047            } else {
2048                Ok((left, ()))
2049            }
2050        }
2051        Err(e) => Err(e),
2052    }
2053}
2054
2055fn blank_node_label3(i: Span) -> IRes<Span> {
2056    take_while(is_pn_chars_or_dot)(i)
2057}
2058
2059/// `[19t] <INTEGER> ::= [+-]? [0-9]+`
2060fn integer<'a>() -> impl FnMut(Span<'a>) -> IRes<'a, i128> {
2061    map_error(
2062        move |i| {
2063            let (i, (maybe_sign, digits)) = tuple((opt(one_of("+-")), digits))(i)?;
2064            let n = match maybe_sign {
2065                None => digits,
2066                Some('+') => digits,
2067                Some('-') => -digits,
2068                _ => panic!("Internal parser error, Strange maybe_sign: {maybe_sign:?}"),
2069            };
2070            Ok((i, n))
2071        },
2072        || ShExParseError::Integer,
2073    )
2074}
2075
2076/// `[20t] <DECIMAL> ::= [+-]? [0-9]* "." [0-9]+`
2077fn decimal(i: Span) -> IRes<NumericLiteral> {
2078    map_res(
2079        pair(
2080            recognize(preceded(opt(sign), digit0)),
2081            preceded(token("."), digit1),
2082        ),
2083        |(whole, fraction)| {
2084            Ok::<_, ParseIntError>(NumericLiteral::decimal_from_parts(
2085                whole.parse()?,
2086                fraction.parse()?,
2087            ))
2088        },
2089    )(i)
2090}
2091
2092/// `[21t] <DOUBLE> ::= [+-]? ([0-9]+ "." [0-9]* EXPONENT | "."? [0-9]+ EXPONENT)`
2093fn double(i: Span) -> IRes<f64> {
2094    map_res(
2095        recognize(preceded(
2096            opt(sign),
2097            alt((
2098                recognize(tuple((digit1, token("."), digit0, exponent))),
2099                recognize(tuple((token("."), digit1, exponent))),
2100                recognize(pair(digit1, exponent)),
2101            )),
2102        )),
2103        |value: LocatedSpan<&str>| value.parse(),
2104    )(i)
2105}
2106
2107fn exponent(input: Span) -> IRes<Span> {
2108    recognize(tuple((one_of("eE"), opt(sign), digit1)))(input)
2109}
2110
2111fn sign(input: Span) -> IRes<Span> {
2112    recognize(one_of("+-"))(input)
2113}
2114
2115fn digits(i: Span) -> IRes<i128> {
2116    map_res(digit1, |number: Span| number.parse::<i128>())(i)
2117}
2118
2119/// `[141s] <PNAME_LN> ::= PNAME_NS PN_LOCAL`
2120fn pname_ln(i: Span) -> IRes<IriRef> {
2121    // This code is different here: https://github.com/vandenoever/rome/blob/047cf54def2aaac75ac4b9adbef08a9d010689bd/src/io/turtle/grammar.rs#L293
2122    let (i, (prefix, local)) = tuple((pname_ns, pn_local))(i)?;
2123    Ok((i, IriRef::prefixed(prefix.fragment(), local)))
2124}
2125
2126/// `[77] <PN_LOCAL> ::= (PN_CHARS_U | ":" | [0-9] | PLX) (PN_CHARS | "." | ":" | PLX)`
2127fn pn_local(i: Span) -> IRes<&str> {
2128    let (i, cs) = recognize(tuple((alt((one_if(is_pn_local_start), plx)), pn_local2)))(i)?;
2129    Ok((i, cs.fragment()))
2130}
2131
2132fn is_pn_local_start(c: char) -> bool {
2133    c == ':' || is_digit(c) || is_pn_chars_u(c)
2134}
2135
2136fn pn_local2(src: Span) -> IRes<()> {
2137    match pn_local3(src) {
2138        Ok((left, m)) => {
2139            // if last is a '.', remove that
2140            if m.ends_with('.') {
2141                // TODO!!: Original parser had this:
2142                // But I need to see how to remove the last character of left...
2143                // Ok(((&src[m.len() - 1..]), ()))
2144                tracing::error!("This code is pending review when the last is a '.' {left}");
2145                Ok((left, ()))
2146            } else {
2147                Ok((left, ()))
2148            }
2149        }
2150        Err(e) => Err(e),
2151    }
2152}
2153
2154fn pn_local3(i: Span) -> IRes<Span> {
2155    recognize(many0(alt((pn_chars_colon, plx, char_dot))))(i)
2156}
2157
2158fn pn_chars_colon(i: Span) -> IRes<Span> {
2159    take_while1(is_pn_chars_colon)(i)
2160}
2161
2162fn is_pn_chars_colon(c: char) -> bool {
2163    c == ':' || is_pn_chars(c)
2164}
2165
2166fn plx(i: Span) -> IRes<Span> {
2167    alt((percent, pn_local_esc))(i)
2168}
2169
2170/// ShEx rule
2171/// `[173s] <PN_LOCAL_ESC> ::= "\\" ( "_" | "~" | "." | "-" | "!" | "$" | "&" | "'" |
2172///             "(" | ")" | "*" | "+" | "," | ";" | "=" | "/" | "?" | "#" | "@" | "%" )``
2173fn pn_local_esc(i: Span) -> IRes<Span> {
2174    recognize(tuple((
2175        char('\\'),
2176        one_if(|c| "_~.-!$&'()*+,;=/?#@%".contains(c)),
2177    )))(i)
2178}
2179
2180fn percent(i: Span) -> IRes<Span> {
2181    recognize(tuple((char('%'), one_if(is_hex), one_if(is_hex))))(i)
2182}
2183
2184fn is_hex(c: char) -> bool {
2185    is_digit(c) || ('a'..='f').contains(&c) || ('A'..='F').contains(&c)
2186}
2187
2188/// `[18t] <IRIREF> ::= "<" ([^#0000- <>\"{}|^`\\] | UCHAR)* ">"`
2189/// iri_chars = ([^#0000- <>\"{}|^`\\] | UCHAR)*
2190fn iri_ref(i: Span) -> IRes<IriS> {
2191    let (i, str) = delimited(
2192        char('<'),
2193        // take_while(is_iri_ref),
2194        iri_chars,
2195        char('>'),
2196    )(i)?;
2197    Ok((i, IriS::new_unchecked(str.as_str())))
2198}
2199
2200/// `[18t] <IRIREF> ::= "<" ([^#0000- <>\"{}|^`\\] | UCHAR)* ">"`
2201/// iri_chars = ([^#0000- <>\"{}|^`\\] | UCHAR)*
2202fn iri_ref_or_str(i: Span) -> IRes<IriOrStr> {
2203    let (i, str) = delimited(
2204        char('<'),
2205        // take_while(is_iri_ref),
2206        iri_chars,
2207        char('>'),
2208    )(i)?;
2209    Ok((i, IriOrStr::new(str.as_str())))
2210}
2211
2212/// `iri_chars = ([^#0000- <>\"{}|^`\\] | UCHAR)*`
2213fn iri_chars(i: Span) -> IRes<String> {
2214    let (i, chars) = many0(iri_char)(i)?;
2215    let s: String = chars.iter().collect();
2216    Ok((i, s))
2217}
2218
2219/// `iri_chars = [^#0000- <>\"{}|^`\\] | UCHAR`
2220fn iri_char(i: Span) -> IRes<char> {
2221    let (i, char) = alt((iri_chr, uchar))(i)?;
2222    Ok((i, char))
2223}
2224
2225#[derive(Error, Debug)]
2226enum UCharError {
2227    #[error("Doesn't start by \\")]
2228    NoStartByBackSlash,
2229
2230    #[error("unescape_code: \\u is not followed by 4 chars")]
2231    LowercaseUNotFollowedBy4chars,
2232
2233    #[error("unescape code: \\U is not followed by 8 chars")]
2234    UppercaseUNotFollowedBy8chars,
2235
2236    #[error("Unexpected {c} after \\")]
2237    UnexpectedCharacterAfterBackSlash { c: char },
2238
2239    #[error("No character after \\")]
2240    NoCharAfterBackSlash,
2241}
2242
2243fn unescape_uchar(str: &str) -> Result<char, UCharError> {
2244    let mut r: char = '?';
2245    let mut queue: VecDeque<_> = str.chars().collect();
2246    while let Some(c) = queue.pop_front() {
2247        if c != '\\' {
2248            return Err(UCharError::NoStartByBackSlash);
2249        }
2250        match queue.pop_front() {
2251            Some('u') => {
2252                let mut s = String::new();
2253                for _ in 0..4 {
2254                    if let Some(c) = queue.pop_front() {
2255                        s.push(c)
2256                    } else {
2257                        return Err(UCharError::LowercaseUNotFollowedBy4chars);
2258                    }
2259                }
2260
2261                let u = u32::from_str_radix(&s, 16).unwrap();
2262                r = char::from_u32(u).unwrap();
2263            }
2264            Some('U') => {
2265                let mut s = String::new();
2266                for _ in 0..8 {
2267                    if let Some(c) = queue.pop_front() {
2268                        s.push(c)
2269                    } else {
2270                        return Err(UCharError::UppercaseUNotFollowedBy8chars);
2271                    }
2272                }
2273
2274                let u = u32::from_str_radix(&s, 16).unwrap();
2275                r = char::from_u32(u).unwrap();
2276            }
2277            Some(c) => return Err(UCharError::UnexpectedCharacterAfterBackSlash { c }),
2278            None => return Err(UCharError::NoCharAfterBackSlash),
2279        }
2280    }
2281    Ok(r)
2282}
2283
2284/// `iri_chr = [^#0000- <>\"{}|^`\\]`
2285fn iri_chr(i: Span) -> IRes<char> {
2286    satisfy(is_iri_ref)(i)
2287}
2288
2289#[inline]
2290fn is_iri_ref(chr: char) -> bool {
2291    chr > ' ' && "<>\"{}|^`\\".find(chr).is_none()
2292}
2293
2294/// [140s] `<PNAME_NS> ::= PN_PREFIX? ":"`
2295fn pname_ns(i: Span) -> IRes<Span> {
2296    let (i, (maybe_pn_prefix, _)) = tuple((opt(pn_prefix), char(':')))(i)?;
2297    Ok((i, maybe_pn_prefix.unwrap_or(Span::from(""))))
2298}
2299
2300/// [168s] `<PN_PREFIX> ::= PN_CHARS_BASE ( (PN_CHARS | ".")* PN_CHARS )?`
2301fn pn_prefix(i: Span) -> IRes<Span> {
2302    /*let (i, (pn_chars_base, maybe_rest)) = tuple((pn_chars_base, opt(rest_pn_prefix)))(i)?;
2303    let mut s: String = pn_chars_base.to_string();
2304    Ok((i, s.as_str()))*/
2305    recognize(tuple((
2306        satisfy(is_pn_chars_base),
2307        take_while(is_pn_chars),
2308        rest_pn_chars, // fold_many0(tuple((char('.'), take_while1(is_pn_chars))), || (), |_, _| ()),
2309    )))(i)
2310}
2311
2312fn rest_pn_chars(i: Span) -> IRes<Vec<Span>> {
2313    let (i, vs) = fold_many0(
2314        tuple((char_dot, take_while1(is_pn_chars))),
2315        Vec::new,
2316        |mut cs: Vec<Span>, (c, rs)| {
2317            cs.push(c);
2318            cs.push(rs);
2319            cs
2320        },
2321    )(i)?;
2322    Ok((i, vs))
2323}
2324
2325/*fn pn_chars_base(i: Span) -> IRes<char> {
2326    satisfy(is_pn_chars_base)(i)
2327}
2328
2329/// From [168s] rest_pn_prefix = (PN_CHARS | ".")* PN_CHARS )
2330fn rest_pn_prefix(i: Span) -> IRes<&str> {
2331    let (i, (vs, cs)) = tuple((many0(alt((pn_chars, char_dot))), pn_chars))(i)?;
2332    // TODO...collect vs
2333    Ok((i, cs.fragment()))
2334}*/
2335
2336fn char_dot(i: Span) -> IRes<Span> {
2337    recognize(char('.'))(i)
2338}
2339
2340/*fn pn_chars(i: Span) -> IRes<Span> {
2341    one_if(is_pn_chars)(i)
2342}*/
2343
2344/// [164s] `<PN_CHARS_BASE> ::= [A-Z] | [a-z]`
2345///        `                | [#00C0-#00D6] | [#00D8-#00F6] | [#00F8-#02FF]`
2346///        `                | [#0370-#037D] | [#037F-#1FFF]`
2347///        `                | [#200C-#200D] | [#2070-#218F] | [#2C00-#2FEF]`
2348///        `                | [#3001-#D7FF] | [#F900-#FDCF] | [#FDF0-#FFFD]`
2349///        `                | [#10000-#EFFFF]`
2350fn is_pn_chars_base(c: char) -> bool {
2351    is_alpha(c)
2352        || in_range(c, 0xC0, 0x00D6)
2353        || in_range(c, 0x00D8, 0x00F6)
2354        || in_range(c, 0x00F8, 0x02FF)
2355        || in_range(c, 0x0370, 0x037D)
2356        || in_range(c, 0x037F, 0x1FFF)
2357        || in_range(c, 0x200C, 0x200D)
2358        || in_range(c, 0x2070, 0x218F)
2359        || in_range(c, 0x2C00, 0x2FEF)
2360        || in_range(c, 0x3001, 0xD7FF)
2361        || in_range(c, 0xF900, 0xFDCF)
2362        || in_range(c, 0xFDF0, 0xFFFD)
2363        || in_range(c, 0x10000, 0xEFFFF)
2364}
2365
2366/// `[165s] <PN_CHARS_U> ::= PN_CHARS_BASE | "_"`
2367fn is_pn_chars_u(c: char) -> bool {
2368    c == '_' || is_pn_chars_base(c)
2369}
2370
2371/// `[167s] <PN_CHARS> ::= PN_CHARS_U | "-" | [0-9]`
2372/// ` | [#00B7] | [#0300-#036F] | [#203F-#2040]`
2373fn is_pn_chars(c: char) -> bool {
2374    is_pn_chars_u(c)
2375        || c == '-'
2376        || is_digit(c)
2377        || c == 0xB7 as char
2378        || in_range(c, 0x0300, 0x036F)
2379        || in_range(c, 0x203F, 0x2040)
2380}
2381
2382fn is_alpha(c: char) -> bool {
2383    c.is_ascii_lowercase() || c.is_ascii_uppercase()
2384}
2385
2386fn is_digit(c: char) -> bool {
2387    c.is_ascii_digit()
2388}
2389
2390fn in_range(c: char, lower: u32, upper: u32) -> bool {
2391    c as u32 >= lower && c as u32 <= upper
2392}
2393
2394/// Take one character if it fits the function
2395fn one_if<'a, F: Fn(char) -> bool>(f: F) -> impl Fn(Span<'a>) -> IRes<'a, Span<'a>> {
2396    move |i| {
2397        if let Some(c) = i.chars().next() {
2398            if f(c) {
2399                Ok(i.take_split(1))
2400            } else {
2401                Err(Err::Error(error_position!(i, ErrorKind::OneOf)))
2402            }
2403        } else {
2404            // Err(Err::Incomplete(Needed::new(1)))
2405            Err(Err::Error(error_position!(i, ErrorKind::OneOf)))
2406        }
2407    }
2408}
2409
2410fn symbol<'a>(value: &'a str) -> impl FnMut(Span<'a>) -> IRes<'a, ()> {
2411    move |i| {
2412        let (i, (_, _, _)) = tuple((tws0, tag_no_case(value), tws0))(i)?;
2413        Ok((i, ()))
2414    }
2415}
2416
2417fn many1_sep<'a, O, O2, F, G, H>(
2418    mut parser_many: F,
2419    mut sep: G,
2420    maker: H,
2421    mut i: Span<'a>,
2422) -> IRes<'a, O2>
2423where
2424    F: FnMut(Span<'a>) -> IRes<'a, O>,
2425    G: FnMut(Span<'a>) -> IRes<'a, ()>,
2426    H: Fn(Vec<O>) -> O2,
2427{
2428    let mut vs = Vec::new();
2429
2430    // skip tws
2431    if let Ok((left, _)) = tws0(i) {
2432        i = left;
2433    }
2434    match parser_many(i) {
2435        Ok((left, v)) => {
2436            vs.push(v);
2437            i = left;
2438        }
2439        Err(e) => return Err(e),
2440    }
2441    loop {
2442        if let Ok((left, _)) = tws0(i) {
2443            i = left;
2444        }
2445
2446        match sep(i) {
2447            Ok((left, _)) => {
2448                i = left;
2449            }
2450            _ => return Ok((i, maker(vs))),
2451        }
2452
2453        if let Ok((left, _)) = tws0(i) {
2454            i = left;
2455        }
2456
2457        match parser_many(i) {
2458            Ok((left, v)) => {
2459                vs.push(v);
2460                i = left;
2461            }
2462            _ => return Ok((i, maker(vs))),
2463        }
2464    }
2465}
2466
2467#[cfg(test)]
2468mod tests {
2469    use super::*;
2470
2471    #[test]
2472    fn test_prefix_id_with_dots() {
2473        let s = shex_statement()(Span::new("prefix a.b.c: <urn>")).unwrap();
2474        assert_eq!(
2475            s.1,
2476            ShExStatement::PrefixDecl {
2477                alias: "a.b.c",
2478                iri: IriS::new_unchecked("urn")
2479            }
2480        );
2481    }
2482
2483    #[test]
2484    fn test_basic_shape_decl() {
2485        let s = shex_statement()(Span::new(":S {}")).unwrap();
2486        assert_eq!(
2487            s.1,
2488            ShExStatement::ShapeDecl {
2489                is_abstract: false,
2490                shape_label: ShapeExprLabel::prefixed("", "S"),
2491                shape_expr: ShapeExpr::empty_shape()
2492            }
2493        );
2494    }
2495
2496    #[test]
2497    fn test_tws_statement() {
2498        assert!(shex_statement()(Span::new(" ")).is_err());
2499    }
2500
2501    /*#[test]
2502    fn test_prefix_id() {
2503        assert_eq!(
2504            prefix_decl("prefix a: <urn>"),
2505            Ok((
2506                "",
2507                ShExStatement::PrefixDecl {
2508                    alias: "a",
2509                    iri: IriS::new_unchecked("urn")
2510                }
2511            ))
2512        );
2513    }
2514
2515    #[test]
2516    fn test_prefix_basic() {
2517        assert_eq!(
2518            prefix_decl("prefix e: <http://example.org/>"),
2519            Ok((
2520                "",
2521                ShExStatement::PrefixDecl {
2522                    alias: "e",
2523                    iri: IriS::new_unchecked("http://example.org/")
2524                }
2525            ))
2526        );
2527    }
2528
2529    #[test]
2530    fn test_directives_prefix_decl() {
2531        assert_eq!(
2532            directives("prefix e: <http://example.org/>"),
2533            Ok((
2534                "",
2535                vec![ShExStatement::PrefixDecl {
2536                    alias: "e",
2537                    iri: IriS::new_unchecked("http://example.org/")
2538                }]
2539            ))
2540        );
2541    }
2542
2543    #[test]
2544    fn test_shex_statement_prefix_decl() {
2545        assert_eq!(
2546            shex_statement("prefix e: <http://example.org/>"),
2547            Ok((
2548                "",
2549                vec![ShExStatement::PrefixDecl {
2550                    alias: "e",
2551                    iri: IriS::new_unchecked("http://example.org/")
2552                }]
2553            ))
2554        );
2555    }
2556
2557    #[test]
2558    fn test_shape_expr_label() {
2559        assert_eq!(
2560            shape_expr_label("<http://example.org/S>"),
2561            Ok(("", Ref::iri_unchecked("http://example.org/S")))
2562        );
2563    }
2564
2565    #[test]
2566    fn test_shape_expr_dot() {
2567        assert_eq!(shape_expression("."), Ok(("", ShapeExpr::any())));
2568    }
2569
2570    #[test]
2571    fn test_shape_expr_triple_constraint() {
2572        let p = IriRef::try_from("http://example.org/p").unwrap();
2573
2574        assert_eq!(
2575            shape_expression("{ <http://example.org/p> . }"),
2576            Ok((
2577                "",
2578                ShapeExpr::shape(
2579                    Shape::default().with_expression(TripleExpr::triple_constraint(
2580                        p,
2581                        Some(ShapeExpr::any()),
2582                        None,
2583                        None
2584                    ))
2585                )
2586            ))
2587        );
2588    }
2589
2590    #[test]
2591    fn test_shape_def_triple_constraint() {
2592        let p = IriRef::try_from("http://example.org/p").unwrap();
2593
2594        assert_eq!(
2595            shape_definition("{ <http://example.org/p> . }"),
2596            Ok((
2597                "",
2598                ShapeExpr::shape(
2599                    Shape::default().with_expression(TripleExpr::triple_constraint(
2600                        p,
2601                        Some(ShapeExpr::any()),
2602                        None,
2603                        None
2604                    ))
2605                )
2606            ))
2607        );
2608    }
2609
2610    #[test]
2611    fn test_triple_expression() {
2612        let p = IriRef::try_from("http://example.org/p").unwrap();
2613
2614        assert_eq!(
2615            triple_expression("<http://example.org/p> . ?"),
2616            Ok((
2617                "",
2618                TripleExpr::triple_constraint(p, Some(ShapeExpr::any()), Some(0), Some(1))
2619            ))
2620        );
2621    }
2622
2623    #[test]
2624    fn test_triple_constraint() {
2625        let p = IriRef::try_from("http://example.org/p").unwrap();
2626
2627        assert_eq!(
2628            unary_triple_expr_opt1("<http://example.org/p> . ?"),
2629            Ok((
2630                "",
2631                TripleExpr::triple_constraint(p, Some(ShapeExpr::any()), Some(0), Some(1))
2632            ))
2633        );
2634    }
2635
2636    #[test]
2637    fn test_shape_expr_and() {
2638        let p = IriRef::try_from("http://example.org/p").unwrap();
2639        let q = IriRef::try_from("http://example.org/q").unwrap();
2640        let se1 = ShapeExpr::shape(Shape::default().with_expression(
2641            TripleExpr::triple_constraint(p, Some(ShapeExpr::any()), None, None),
2642        ));
2643        let se2 = ShapeExpr::shape(Shape::default().with_expression(
2644            TripleExpr::triple_constraint(q, Some(ShapeExpr::any()), None, None),
2645        ));
2646        assert_eq!(
2647            shape_expression("{ <http://example.org/p> . } AND { <http://example.org/q> . }"),
2648            Ok(("", ShapeExpr::and(vec![se1, se2])))
2649        );
2650    }*/
2651
2652    /*#[test]
2653    fn test_empty_shex_statement() {
2654        let (_, result) = shex_statement()(Span::new("")).unwrap();
2655        let expected = Vec::new();
2656        assert_eq!(result, expected)
2657    }*/
2658
2659    #[test]
2660    fn test_string_literal() {
2661        let (_, result) = string_literal1()(Span::new("'a'")).unwrap();
2662        let expected = "a".to_string();
2663        assert_eq!(result, expected)
2664    }
2665
2666    #[test]
2667    fn test_iri_ref_uchar() {
2668        let (_, result) = iri_ref(Span::new("<http://example.org/p\\u0031>")).unwrap();
2669        let expected = IriS::new_unchecked("http://example.org/p1");
2670        assert_eq!(result, expected)
2671    }
2672
2673    #[test]
2674    fn test_value_set() {
2675        let (_, result) = value_set()(Span::new("[ 'a' ]")).unwrap();
2676        let expected_values = vec![ValueSetValue::string_literal("a", None)];
2677        let expected = NodeConstraint::new().with_values(expected_values);
2678        assert_eq!(result, expected)
2679    }
2680
2681    #[test]
2682    fn test_node_constraint_value_set() {
2683        let (_, result) = lit_node_constraint()(Span::new("[ 'a' ]")).unwrap();
2684        let expected_values = vec![ValueSetValue::string_literal("a", None)];
2685        let expected = NodeConstraint::new().with_values(expected_values);
2686        assert_eq!(result, expected)
2687    }
2688
2689    #[test]
2690    fn test_shape_atom_node_constraint() {
2691        let (_, result) = lit_node_constraint_shape_expr()(Span::new("[ 'a' ]")).unwrap();
2692        let expected_values = vec![ValueSetValue::string_literal("a", None)];
2693        let expected =
2694            ShapeExpr::NodeConstraint(NodeConstraint::new().with_values(expected_values));
2695        assert_eq!(result, expected)
2696    }
2697
2698    #[test]
2699    fn test_triple_constraint() {
2700        let (_, result) = triple_constraint()(Span::new(":p xsd:int")).unwrap();
2701        let nc = ShapeExpr::node_constraint(
2702            NodeConstraint::new().with_datatype(IriRef::prefixed("xsd", "int")),
2703        );
2704        let expected = TripleExpr::triple_constraint(
2705            None,
2706            None,
2707            IriRef::prefixed("", "p"),
2708            Some(nc),
2709            None,
2710            None,
2711        );
2712        assert_eq!(result, expected)
2713    }
2714
2715    #[test]
2716    fn test_inline_shape_expr() {
2717        let (_, result) = inline_shape_expression()(Span::new(":p")).unwrap();
2718        let expected = ShapeExpr::node_constraint(
2719            NodeConstraint::new().with_datatype(IriRef::prefixed("", "p")),
2720        );
2721        assert_eq!(result, expected)
2722    }
2723
2724    #[test]
2725    fn test_numeric_literal() {
2726        let (_, result) = numeric_literal(Span::new("0")).unwrap();
2727        let expected = NumericLiteral::integer(0);
2728        assert_eq!(result, expected)
2729    }
2730
2731    /*#[test]
2732    fn test_incomplete() {
2733        use super::*;
2734
2735        fn m(i: &str) -> IResult<&str, ShapeExpr> {
2736            let (i, s) = shape_definition(i)?;
2737            Ok((i, s))
2738        }
2739        let te = TripleExpr::triple_constraint(
2740            IriRef::prefixed("","p"),
2741            Some(ShapeExpr::iri_ref(IriRef::prefixed("", "User"))),
2742            Some(0),
2743            Some(-1));
2744        assert_eq!(m("{ :p @:User * ; }"), Ok(((""),
2745          ShapeExpr::shape(Shape::new(None, None, Some(te)))
2746          )))
2747    }*/
2748}