sophia_api/
ns.rs

1//! Standard and custom namespaces.
2//!
3//! This module provides:
4//! * the [`Namespace`](struct.Namespace.html) type for defining custom dynamic namespace;
5//! * the [`namespace`](crate::namespace) macro, for defning custom static namespaces;
6//! * modules corresponding to the most common namespaces
7//!   (generated via the [`namespace`](crate::namespace) macro).
8//!
9//! # Example use
10//! ```
11//! use sophia_api::ns::{Namespace, rdf, rdfs, xsd};
12//!
13//! let schema = Namespace::new("http://schema.org/").unwrap();
14//! let s_name = schema.get("name").unwrap();
15//!
16//! // you can now populate a graph like this:
17//! let mut g = vec![];
18//! g.push([&s_name, &rdf::type_, &rdf::Property]);
19//! g.push([&s_name, &rdfs::range, &xsd::string]);
20//! ```
21//!
22//! # Datatyped literals
23//!
24//! Note also that the terms generated via the [`namespace`](crate::namespace) macro
25//! can be used to easily produce datatyped literals,
26//! by simply "multiplying" a string by its datatype:
27//!
28//! ```
29//! # use sophia_api::{term::Term, ns::xsd};
30//! let date = "2023-11-15" * xsd::date ;
31//! assert!(date.is_literal());
32//! assert_eq!(date.lexical_form().unwrap(), "2023-11-15");
33//! assert_eq!(date.datatype().unwrap(), xsd::date.iri().unwrap());
34//! ```
35use mownstr::MownStr;
36use sophia_iri::InvalidIri;
37use std::borrow::Borrow;
38use std::fmt;
39
40// rexport is necessary to ensure that the macros work.
41pub use sophia_iri::IriRef;
42
43#[macro_use]
44mod _macro;
45pub use _macro::*;
46mod _namespace;
47pub use _namespace::*;
48mod _term;
49pub use _term::*;
50
51/// The standard `rdf:` namespace.
52///
53/// NB: since `type` is a reserved keyword in Rust,
54/// the term `rdf:type` spells `rdf::type_` (with a trailing underscore).
55///
56pub mod rdf {
57    namespace!(
58        "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
59        // classes
60        Alt,
61        Bag,
62        List,
63        PlainLiteral,
64        Property,
65        Seq,
66        Statement,
67        // datatypes
68        HTML,
69        JSON,
70        langString,
71        XMLLiteral,
72        // properties
73        direction,
74        first,
75        language,
76        object,
77        predicate,
78        rest,
79        subject,
80        value,
81        // individuals
82        nil,
83        // core syntax terms
84        RDF,
85        ID,
86        Description,
87        about,
88        parseType,
89        resource,
90        li,
91        nodeID,
92        datatype,
93        bagID,
94        aboutEach,
95        aboutEachPrefix;
96        // 'type' is a Rust keyword, so we use 'type_' instead
97        type_, "type"
98    );
99}
100
101/// The standard `xsd:` namespace.
102#[rustfmt::skip]
103pub mod xsd {
104    namespace!(
105        "http://www.w3.org/2001/XMLSchema#",
106        anyType,
107        anySimpleType,
108            duration,
109            dateTime,
110            time,
111            date,
112            gYearMonth,
113            gYear,
114            gMonthDay,
115            gDay,
116            gMonth,
117            boolean,
118            base64Binary,
119            hexBinary,
120            float,
121            double,
122            anyURI,
123            QName,
124            NOTATION,
125            string,
126                normalizedString,
127                    token,
128                        language,
129                        Name,
130                            NCName,
131                                ID,
132                                IDREF,
133                                    IDREFS,
134                                ENTITY,
135                                    ENTITIES,
136                        NMTOKEN,
137                        NMTOKENS,
138            decimal,
139                integer,
140                    nonPositiveInteger,
141                        negativeInteger,
142                    long,
143                        int,
144                            short,
145                                byte,
146                    nonNegativeInteger,
147                        unsignedLong,
148                            unsignedInt,
149                                unsignedShort,
150                                    unsignedByte,
151                        positiveInteger
152    );
153}
154
155/// The standard `rdfs:` namespace.
156pub mod rdfs {
157    namespace!(
158        "http://www.w3.org/2000/01/rdf-schema#",
159        // types
160        Class,
161        Container,
162        ContainerMembershipProperty,
163        Datatype,
164        Literal,
165        Resource,
166        // semantic properties
167        domain,
168        range,
169        subClassOf,
170        subPropertyOf,
171        // documentation properties
172        comment,
173        isDefinedBy,
174        label,
175        member,
176        seeAlso
177    );
178}
179
180/// The standard `xml:` namespace
181pub mod xml {
182    namespace!(
183        "http://www.w3.org/XML/1998/namespace#",
184        lang,
185        space,
186        base,
187        id,
188        // Jon Bosak
189        Father
190    );
191}
192
193/// The standard `owl:` namespace
194pub mod owl {
195    namespace!(
196        "http://www.w3.org/2002/07/owl#",
197        Nothing,
198        Thing,
199        // Classes
200        AllDifferent,
201        AllDisjointClasses,
202        AnnotationProperty,
203        Class,
204        DatatypeProperty,
205        FunctionalProperty,
206        InverseFunctionalProperty,
207        IrreflexiveProperty,
208        ObjectProperty,
209        SymmetricProperty,
210        TransitiveProperty,
211        // Properties
212        allValuesFrom,
213        assertionProperty,
214        complementOf,
215        differentFrom,
216        disjointWith,
217        distinctMembers,
218        equivalentClass,
219        equivalentProperty,
220        intersectionOf,
221        inverseOf,
222        maxCardinality,
223        maxQualifiedCardinality,
224        members,
225        onClass,
226        oneOf,
227        onProperty,
228        propertyChainAxiom,
229        propertyDisjointWith,
230        sameAs,
231        someValuesFrom,
232        sourceIndividual,
233        targetIndividual,
234        targetValue,
235        unionOf
236    );
237}
238
239#[cfg(test)]
240mod test {
241    // Nothing really worth testing here
242    use super::*;
243    use std::rc::Rc;
244
245    #[test]
246    fn test_same_term() {
247        let ns1 = Namespace::new("http://schema.org/").unwrap();
248        let ns2 = Namespace::new(Rc::from("http://schema.org/")).unwrap();
249
250        assert_eq!(
251            ns1.get("name").unwrap().to_string(),
252            ns1.get("name").unwrap().to_string()
253        );
254        assert_eq!(
255            ns2.get("name").unwrap().to_string(),
256            ns2.get("name").unwrap().to_string()
257        );
258        assert_eq!(
259            ns1.get("name").unwrap().to_string(),
260            ns2.get("name").unwrap().to_string()
261        );
262    }
263
264    #[test]
265    fn test_different_terms() {
266        let ns1 = Namespace::new("http://schema.org/").unwrap();
267        assert_ne!(
268            ns1.get("name").unwrap().to_string(),
269            ns1.get("nam").unwrap().to_string()
270        );
271    }
272
273    #[test]
274    fn test_invalid_namespace() {
275        assert!(Namespace::new("http://schema.org ").is_err());
276    }
277
278    #[test]
279    fn test_invalid_suffix() {
280        let ns1 = Namespace::new("http://schema.org/").unwrap();
281        assert!(ns1.get("name ").is_err());
282    }
283}