srdf/
lib.rs

1//! This crate contains a _Simple_ RDF wrapper which can be useful to work with RDF data
2//!
3//! It contains several traits that handle RDF data:
4//! - [`SRDFBasic`]: Basic comparisons on RDF nodes
5//! - [`SRDF`]: Definitions on RDF graphs
6//! - [`FocusRDF`]: RDF graphs with a focus node
7//! - [`RDFNodeParse`]: RDF graphs that can be parsed
8pub mod async_srdf;
9pub mod bnode;
10pub mod iri;
11pub mod iri_or_blanknode;
12pub mod lang;
13pub mod literal;
14pub mod matcher;
15pub mod neighs;
16pub mod neighs_rdf;
17pub mod numeric_literal;
18pub mod object;
19pub mod oxrdf_impl;
20pub mod query_rdf;
21pub mod query_result_format;
22pub mod rdf;
23pub mod rdf_data_config;
24pub mod rdf_format;
25pub mod rdf_visualizer;
26pub mod regex;
27pub mod shacl_path;
28pub mod sliteral;
29pub mod sparql_query;
30pub mod srdf_builder;
31pub mod srdf_error;
32pub mod srdf_graph;
33pub mod srdf_parser;
34pub mod srdf_sparql;
35pub mod subject;
36pub mod term;
37pub mod triple;
38pub mod uml_converter;
39pub mod vocab;
40pub mod xsd_datetime;
41
42pub use crate::async_srdf::*;
43pub use crate::neighs::*;
44pub use crate::neighs_rdf::*;
45pub use crate::query_rdf::*;
46pub use crate::rdf::*;
47pub use crate::rdf_data_config::*;
48pub use bnode::*;
49pub use iri::*;
50pub use iri_or_blanknode::*;
51pub use literal::*;
52pub use object::*;
53pub use oxrdf_impl::*;
54pub use query_result_format::*;
55pub use rdf_format::*;
56pub use regex::*;
57pub use shacl_path::*;
58pub use sliteral::*;
59pub use sparql_query::*;
60pub use srdf_builder::*;
61pub use srdf_error::*;
62pub use srdf_graph::*;
63pub use srdf_parser::*;
64pub use srdf_sparql::*;
65pub use subject::*;
66pub use term::*;
67pub use triple::*;
68pub use uml_converter::*;
69pub use vocab::*;
70pub use xsd_datetime::*;
71
72/// Concrete representation of RDF nodes, which are equivalent to objects
73pub type RDFNode = Object;
74
75/// Concrete representation of the kind of RDF terms, which can be IRIs, blank nodes, literals or triples
76#[derive(PartialEq)]
77pub enum TermKind {
78    Iri,
79    BlankNode,
80    Literal,
81    Triple,
82}
83
84/// Creates an integer literal
85///
86#[macro_export]
87macro_rules! int {
88    (
89        $n: tt
90      ) => {
91        $crate::literal::Literal::integer($n)
92    };
93}
94
95/// Declares a named RDF parser which can be reused.
96///
97/// The expression which creates the parser should have no side effects as it may be called
98/// multiple times even during a single parse attempt.
99///
100/// This macro is useful when declaring mutually recursive parsers
101///
102/// ```
103///
104/// #[macro_use]
105/// use iri_s::IriS;
106/// use srdf::{rdf_parser, RDFParser, RDF, RDFFormat, FocusRDF, satisfy, ReaderMode, RDFNodeParse, Rdf, property_value, rdf_list, set_focus};
107/// use srdf::srdf_graph::SRDFGraph;
108///
109/// rdf_parser!{
110///       fn is_term['a, RDF](term: &'a RDF::Term)(RDF) -> ()
111///       where [
112///       ] {
113///        let name = format!("is_{term}");
114///        satisfy(|t| { t == *term }, name.as_str())
115///       }
116/// }
117///
118/// let s = r#"prefix : <http://example.org/>
119///            :x :p 1.
120/// "#;
121/// let mut graph = SRDFGraph::from_str(s, &RDFFormat::Turtle, None, &ReaderMode::default()).unwrap();
122/// let x = IriS::new_unchecked("http://example.org/x");
123/// let term = x.clone().into();
124/// assert_eq!(is_term(&term).parse(&x, graph).unwrap(), ())
125/// ````
126#[macro_export]
127macro_rules! rdf_parser {
128 (
129   $(#[$attr:meta])*
130   $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),*)
131     ($input_type: ty) -> $output_type: ty
132   where [$($where_clause: tt)*]
133     $parser: block
134 ) => {
135    $crate::combine_rdf_parser_impl!{
136      #[allow(non_camel_case_types)]
137      #[doc(hidden)]
138      $fn_vis struct $name;
139      $(#[$attr])*
140      $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
141         where [$($where_clause)*]
142      $parser
143 }
144 };
145}
146
147/// Auxiliary macro that is invoked from `rdf_parser`
148/// Supports different templates
149#[macro_export]
150macro_rules! combine_rdf_parser_impl {
151    (
152        $(#[$derive:meta])*
153        $struct_vis: vis struct $type_name: ident;
154        $(#[$attr:meta])*
155        $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),*)
156            ($input_type: ty) -> $output_type: ty
157            where [$($where_clause: tt)*]
158        $parser: block
159    ) => {
160
161        $(#[$derive])*
162        $struct_vis struct $type_name<$($type_params)*>
163            where
164             $input_type : $crate::FocusRDF + 'static,
165             $($where_clause)*
166        {
167            $(pub $arg : $arg_type,)*
168            __marker: ::std::marker::PhantomData<$input_type>,
169        }
170
171        impl <$($type_params)*> $crate::RDFNodeParse<$input_type> for $type_name<$($type_params)*>
172            where
173                $input_type : $crate::FocusRDF + 'static,
174                $($where_clause)*
175        {
176
177            type Output = $output_type;
178
179            #[inline]
180            fn parse_impl(
181                &mut self,
182                input: &mut $input_type,
183                ) -> $crate::srdf_parser::PResult<$output_type>
184            {
185                let $type_name { $( $arg: ref mut $arg,)* .. } = *self;
186                let r = $parser.parse_impl(input)?;
187                Ok(r)
188            }
189        }
190
191        $(#[$attr])*
192        #[inline]
193        $fn_vis fn $name< $($type_params)* >(
194                $($arg : $arg_type),*
195            ) -> $type_name<$($type_params)*>
196            where
197                $input_type: $crate::FocusRDF + 'static,
198                $($where_clause)*
199        {
200            $type_name {
201                $($arg,)*
202                __marker: ::std::marker::PhantomData,
203            }
204        }
205    }
206}
207
208#[macro_export]
209macro_rules! combine_parsers {
210    ($first : expr) => {
211        $first
212    };
213    ($first : expr, $($rest : expr),+) => {
214        combine_vec($first, combine_parsers!($($rest),+))
215    }
216}
217
218/// Convenience macro over [`opaque`][].
219/// This macro can be useful to combine parsers which can have some underlying different opaque types
220/// In this way, we can avoid some compiler performance problems when using `combine_parsers!` over a large number of parsers that are implemented as `impl RDFNodeParse`
221///  
222#[macro_export]
223macro_rules! opaque {
224    ($e: expr) => {
225        $crate::opaque!($e,);
226    };
227    ($e: expr,) => {
228        opaque(move |f: &mut dyn FnMut(&mut dyn RDFNodeParse<_, Output = _>)| f(&mut $e))
229    };
230}
231
232/// Alias over `Opaque` where the function can be a plain function pointer
233pub type FnOpaque<RDF, O> =
234    Opaque<fn(&mut dyn FnMut(&mut dyn RDFNodeParse<RDF, Output = O>)), RDF, O>;
235
236/// Name of Environment variable where we search for plantuml JAR
237pub const PLANTUML: &str = "PLANTUML";