shex_ast/shexr/
shexr_parser.rs

1use super::shexr_error::ShExRError;
2use super::*;
3use crate::{
4    BNode, NodeConstraint, NodeKind, ObjectValue, Schema, Shape, ShapeDecl, ShapeExpr,
5    ShapeExprLabel, ValueSetValue,
6};
7use iri_s::IriS;
8use prefixmap::IriRef;
9use srdf::rdf_parser;
10use srdf::srdf_parser::*;
11use srdf::FocusRDF;
12use srdf::RDFParseError;
13use srdf::{Object, RDFParser};
14
15type Result<A> = std::result::Result<A, ShExRError>;
16
17pub struct ShExRParser<RDF>
18where
19    RDF: FocusRDF,
20{
21    rdf_parser: RDFParser<RDF>,
22}
23
24impl<RDF> ShExRParser<RDF>
25where
26    RDF: FocusRDF,
27{
28    pub fn new(rdf: RDF) -> ShExRParser<RDF> {
29        ShExRParser {
30            rdf_parser: RDFParser::new(rdf),
31        }
32    }
33
34    pub fn parse(&mut self) -> Result<Schema> {
35        let schema = Self::schema_parser()
36            .parse_impl(&mut self.rdf_parser.rdf)
37            .map_err(|e| ShExRError::RDFParseError { err: e })?;
38        let prefixmap = self.rdf_parser.prefixmap();
39        Ok(schema.with_prefixmap(prefixmap))
40    }
41
42    pub fn schema_parser() -> impl RDFNodeParse<RDF, Output = Schema> {
43        instance_of(&ShExRVocab::sx_schema())
44            .then(|node| set_focus_subject(node).then(|_| Self::schema()))
45    }
46
47    fn schema() -> impl RDFNodeParse<RDF, Output = Schema> {
48        property_value(&sx_shapes()).then(|ref node| {
49            set_focus(node)
50                .and(parse_rdf_list::<RDF, _>(Self::shape_decl()))
51                .map(|(_, vs)| Schema::new().with_shapes(Some(vs)))
52        })
53    }
54
55    fn term_to_shape_label(term: &RDF::Term) -> Result<ShapeExprLabel> {
56        let object = term.clone().into();
57        match object {
58            Object::Iri(iri) => Ok(ShapeExprLabel::iri(iri)),
59            Object::BlankNode(bnode) => Ok(ShapeExprLabel::bnode(BNode::new(bnode.as_str()))),
60            Object::Literal(lit) => Err(ShExRError::ShapeExprLabelLiteral {
61                term: lit.to_string(),
62            }),
63        }
64    }
65
66    fn shape_decl() -> impl RDFNodeParse<RDF, Output = ShapeDecl> {
67        (term().flat_map(move |ref t| {
68            let label = Self::term_to_shape_label(t).map_err(|e| RDFParseError::Custom {
69                msg: format!("Expected term to be a label: {t}: {e}"),
70            })?;
71            Ok(label)
72        }))
73        .and(Self::parse_shape_expr())
74        .map(|(label, se)| ShapeDecl::new(label, se, false))
75    }
76
77    fn parse_shape_expr() -> impl RDFNodeParse<RDF, Output = ShapeExpr> {
78        property_value(&sx_shape_expr()).then(|ref node| set_focus(node).then(|_| shape_expr()))
79    }
80}
81
82fn shape_expr_<RDF>() -> impl RDFNodeParse<RDF, Output = ShapeExpr>
83where
84    RDF: FocusRDF,
85{
86    // I would like the following code to work...but it doesn't yet...
87    /*parse_by_type(vec![
88     (sx_shape_and(), shape_and()),
89     . . .
90     (sx_node_constraint(), node_constraint())
91    ], default) */
92
93    shape_and().or(shape_or()).or(shape()).or(node_constraint())
94}
95
96fn shape<RDF>() -> impl RDFNodeParse<RDF, Output = ShapeExpr>
97where
98    RDF: FocusRDF,
99{
100    has_type(sx_shape()).with({
101        closed().then(|maybe_closed| {
102            let extra = None; // TODO
103            let expression = None; // TODO
104            ok(&ShapeExpr::shape(Shape::new(
105                maybe_closed,
106                extra,
107                expression,
108            )))
109        })
110    })
111}
112
113fn closed<RDF>() -> impl RDFNodeParse<RDF, Output = Option<bool>>
114where
115    RDF: FocusRDF,
116{
117    optional(property_bool(&sx_closed()))
118}
119
120rdf_parser! {
121    pub fn shape_and[RDF]()(RDF) -> ShapeExpr where [] {
122        has_type(sx_shape_and()).with(
123        property_value(&sx_shape_exprs()).then(|ref node| {
124            set_focus(node).and(
125                   parse_rdf_list::<RDF, _>(shape_expr())
126                 ).map(|(_,vs)| { ShapeExpr::and(vs) })
127           }))
128    }
129}
130
131rdf_parser! {
132    pub fn shape_or[RDF]()(RDF) -> ShapeExpr where [] {
133        has_type(sx_shape_or()).with(
134        property_value(&sx_shape_exprs()).then(|ref node| {
135            set_focus(node).and(
136                   parse_rdf_list::<RDF, _>(shape_expr())
137                 ).map(|(_,vs)| { ShapeExpr::or(vs) })
138           }))
139    }
140}
141
142rdf_parser! {
143    pub fn shape_expr[RDF]()(RDF) -> ShapeExpr where [] {
144       shape_expr_()
145    }
146}
147
148/*
149#[inline]
150fn sx_schema<RDF>() -> RDF::Term
151where
152    RDF: FocusRDF,
153{
154    RDFParser::<RDF>::term_iri_unchecked(SX_SCHEMA)
155}
156*/
157
158#[inline]
159fn sx_shapes() -> IriS {
160    IriS::new_unchecked(SX_SHAPES)
161}
162
163fn sx_shape_expr() -> IriS {
164    IriS::new_unchecked(SX_SHAPE_EXPR)
165}
166
167fn sx_closed() -> IriS {
168    IriS::new_unchecked(SX_CLOSED)
169}
170
171#[inline]
172fn sx_values() -> IriS {
173    IriS::new_unchecked(SX_VALUES)
174}
175
176#[inline]
177fn sx_shape() -> IriS {
178    IriS::new_unchecked(SX_SHAPE)
179}
180
181#[inline]
182fn sx_shape_exprs() -> IriS {
183    IriS::new_unchecked(SX_SHAPE_EXPRS)
184}
185
186#[inline]
187fn sx_node_kind() -> IriS {
188    IriS::new_unchecked(SX_NODEKIND)
189}
190
191fn sx_shape_and() -> IriS {
192    IriS::new_unchecked(SX_SHAPE_AND)
193}
194
195fn sx_shape_or() -> IriS {
196    IriS::new_unchecked(SX_SHAPE_OR)
197}
198
199/*
200fn sx_node_constraint() -> IriS {
201    IriS::new_unchecked(SX_NODECONSTRAINT)
202}
203*/
204
205rdf_parser! {
206 fn node_constraint[RDF]()(RDF) -> ShapeExpr
207 where [] {
208    parse_nodekind().then(|maybe_nodekind|
209        parse_value_set().then(move |maybe_valueset| {
210           let mut nc = NodeConstraint::new();
211           if let Some(nk) = &maybe_nodekind {
212              nc = nc.with_node_kind(nk.clone());
213           }
214           if let Some(vs) = &maybe_valueset {
215              nc = nc.with_values(vs.clone())
216           }
217           ok(&ShapeExpr::node_constraint(nc))
218         }
219        )
220    )
221  }
222}
223
224fn parse_nodekind<RDF>() -> impl RDFNodeParse<RDF, Output = Option<NodeKind>>
225where
226    RDF: FocusRDF,
227{
228    optional(
229        property_value(&sx_node_kind())
230            .then(|ref node| set_focus(node).and(nodekind()).map(|(_, vs)| vs)),
231    )
232}
233
234fn nodekind<RDF>() -> impl RDFNodeParse<RDF, Output = NodeKind>
235where
236    RDF: FocusRDF,
237{
238    iri_kind()
239        .or(literal_kind())
240        .or(bnode_kind())
241        .or(nonliteral_kind())
242}
243
244fn iri_kind<RDF>() -> impl RDFNodeParse<RDF, Output = NodeKind>
245where
246    RDF: FocusRDF,
247{
248    is_iri(ShExRVocab::sx_iri()).map(|_| NodeKind::Iri)
249}
250
251fn literal_kind<RDF>() -> impl RDFNodeParse<RDF, Output = NodeKind>
252where
253    RDF: FocusRDF,
254{
255    is_iri(ShExRVocab::sx_literal()).map(|_| NodeKind::Literal)
256}
257
258fn bnode_kind<RDF>() -> impl RDFNodeParse<RDF, Output = NodeKind>
259where
260    RDF: FocusRDF,
261{
262    is_iri(ShExRVocab::sx_bnode()).map(|_| NodeKind::BNode)
263}
264
265fn nonliteral_kind<RDF>() -> impl RDFNodeParse<RDF, Output = NodeKind>
266where
267    RDF: FocusRDF,
268{
269    is_iri(ShExRVocab::sx_nonliteral()).map(|_| NodeKind::NonLiteral)
270}
271
272fn parse_value_set<RDF>() -> impl RDFNodeParse<RDF, Output = Option<Vec<ValueSetValue>>>
273where
274    RDF: FocusRDF,
275{
276    optional(property_value(&sx_values()).then(|ref node| {
277        set_focus(node)
278            .and(parse_rdf_list::<RDF, _>(parse_value()))
279            .map(|(_, vs)| vs)
280    }))
281}
282
283fn parse_value<RDF>() -> impl RDFNodeParse<RDF, Output = ValueSetValue>
284where
285    RDF: FocusRDF,
286{
287    //firstOf(objectValue, )
288    object_value().map(ValueSetValue::ObjectValue)
289}
290
291fn object_value<RDF>() -> impl RDFNodeParse<RDF, Output = ObjectValue>
292where
293    RDF: FocusRDF,
294{
295    iri().map(|ref iri| ObjectValue::IriRef(IriRef::Iri(iri.clone())))
296}