Expand description
purrdf-shex — the native ShEx 2.1 engine for PurRDF: the schema
layer and the shape-map validator.
A pure-Rust, wasm-clean leaf crate implementing the Shape Expressions language, 2.1 (https://shex.io/shex-semantics/):
parse_shexc— a hand-rolled lexer + recursive-descent parser for the compact syntax (spec §6): directives,start, shape declarations, theAND/OR/NOTalgebra, node constraints and facets, value sets with stems/ranges/exclusions, triple expressions with every cardinality form,$/&labels and inclusions,^inverse, annotations and semantic actions, with relative-IRI resolution againstBASEviapurrdf-iri.parse_shexj/to_shexj— the ShExJ JSON wire format (spec Appendix A), byte-compatible with theshexTestground-truth corpus.check_structure— the spec §5.7 structural requirements (dangling references, label collisions, reference-only cycles, the negation requirement), what thenegativeStructuresuite exercises.validate()— the shape-map validator (spec §5.2–§5.5): fixed(node, shape)associations checked over a frozenpurrdf_core::RdfDatasetin internedTermIdspace, with node constraints,EXTRA/CLOSEDtriple-expression matching, and typing-based recursion; gated against the shexTestvalidation/manifest bytests/validation_conformance.rs.
§Hard-fail
Per the repo no-optionality doctrine, every malformed schema is a typed
ShexError / StructureError; there is no lenient mode and no panic
on any input (parsers are fuzz-safe and depth-bounded).
§Conformance
tests/syntax_conformance.rs runs the vendored shexTest v2.1.0 corpus
(vectors/shexTest): every negativeSyntax/ document must fail
parse_shexc, every negativeStructure/ document must parse and fail
check_structure, and every schemas/ pair must parse in both
syntaxes; tests/shexj_roundtrip.rs proves parse_shexj → to_shexj → parse_shexj is the identity on the corpus;
tests/validation_conformance.rs runs the full validation/ manifest
(with an exact-count trait skip list and xfail ledger).
§Examples
Parse a ShExC schema and validate a node against a small Turtle graph
(Turtle parsing via purrdf-rdf; any source of a frozen
purrdf_core::RdfDataset works):
use purrdf_rdf::parse_dataset;
use purrdf_shex::{ValidationOptions, parse_shexc, validate_shape_map};
let schema = parse_shexc(
"<http://example.org/UserShape> { <http://example.org/name> LITERAL }",
None,
)
.expect("a well-formed schema parses");
let data = parse_dataset(
b"<http://example.org/alice> <http://example.org/name> \"Alice\" .",
"text/turtle",
None,
)
.expect("a well-formed graph parses");
let result = validate_shape_map(
&schema,
&data,
"<http://example.org/alice>@<http://example.org/UserShape>",
None,
&ValidationOptions::default(),
)
.expect("a well-formed shape map parses");
assert!(result.all_conformant());Re-exports§
pub use ast::Annotation;pub use ast::IriExclusion;pub use ast::LanguageExclusion;pub use ast::LiteralExclusion;pub use ast::NodeConstraint;pub use ast::NodeKind;pub use ast::NumericLiteral;pub use ast::ObjectLiteral;pub use ast::ObjectValue;pub use ast::Schema;pub use ast::SemAct;pub use ast::Shape;pub use ast::ShapeDecl;pub use ast::ShapeExpr;pub use ast::ShapeLabel;pub use ast::StemValue;pub use ast::TripleConstraint;pub use ast::TripleExpr;pub use ast::TripleExprGroup;pub use ast::ValueSetValue;pub use error::Result;pub use error::ShexError;pub use imports::ImportResolver;pub use imports::resolve_imports;pub use parser::parse_shexc;pub use semact::SemActContext;pub use semact::SemActExtension;pub use semact::SemActRegistry;pub use semact::TEST_EXTENSION;pub use shapemap::NodeSelector;pub use shapemap::ShapeAssociation;pub use shapemap::ShapeMap;pub use shapemap::parse_shape_map;pub use shapemap::resolve_shape_map;pub use shapemap::validate_shape_map;pub use shexc::to_shexc;pub use shexj::parse_shexj;pub use shexj::to_shexj;pub use structure::StructureError;pub use structure::check_structure;pub use validate::ConformanceStatus;pub use validate::ExternalResolver;pub use validate::ResultEntry;pub use validate::ResultShapeMap;pub use validate::ShapeSelector;pub use validate::ValidationOptions;pub use validate::validate;pub use validate::validate_with;
Modules§
- ast
- The ShExJ-aligned ShEx 2.1 abstract syntax tree.
- error
- Typed ShEx parse failures.
- imports
IMPORTresolution (ShEx 2.1 spec §11 / ShExJimports).- lexer
- A hand-rolled ShExC (ShEx 2.1 §6) tokenizer.
- parser
- The recursive-descent ShExC parser (ShEx 2.1 spec §6 grammar).
- semact
- Semantic-action dispatch (ShEx 2.1 spec §5.5.2 / ShExJ
SemAct). - shapemap
- Query shape maps (the ShapeMap spec, https://shex.io/shape-map/).
- shexc
- ShExC — the compact syntax serializer for ShEx schemas (spec §6).
- shexj
- ShExJ — the JSON(-LD) wire format for ShEx schemas (spec Appendix A).
- structure
- Post-parse structural well-formedness (ShEx 2.1 spec §5.7, “Schema
Requirements”) — what the
negativeStructureconformance suite checks. - validate
- The ShEx 2.1 shape-map validator (spec §5.2–§5.5).