shex_ast/shexr/
shexr_parser.rs1use 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 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; let expression = None; 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#[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
199rdf_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 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}