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;
45mod _namespace;
46pub use _namespace::*;
47mod _term;
48pub use _term::*;
49
50/// The standard `rdf:` namespace.
51///
52/// NB: since `type` is a reserved keyword in Rust,
53/// the term `rdf:type` spells `rdf::type_` (with a trailing underscore).
54///
55pub mod rdf {
56    namespace!(
57        "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
58        // classes
59        Alt,
60        Bag,
61        List,
62        PlainLiteral,
63        Property,
64        Seq,
65        Statement,
66        // datatypes
67        HTML,
68        JSON,
69        langString,
70        XMLLiteral,
71        // properties
72        direction,
73        first,
74        language,
75        object,
76        predicate,
77        rest,
78        subject,
79        value,
80        // individuals
81        nil,
82        // core syntax terms
83        RDF,
84        ID,
85        Description,
86        about,
87        parseType,
88        resource,
89        li,
90        nodeID,
91        datatype,
92        bagID,
93        aboutEach,
94        aboutEachPrefix;
95        // 'type' is a Rust keyword, so we use 'type_' instead
96        type_, "type"
97    );
98}
99
100/// The standard `xsd:` namespace.
101#[rustfmt::skip]
102pub mod xsd {
103    namespace!(
104        "http://www.w3.org/2001/XMLSchema#",
105        anyType,
106        anySimpleType,
107            duration,
108            dateTime,
109            time,
110            date,
111            gYearMonth,
112            gYear,
113            gMonthDay,
114            gDay,
115            gMonth,
116            boolean,
117            base64Binary,
118            hexBinary,
119            float,
120            double,
121            anyURI,
122            QName,
123            NOTATION,
124            string,
125                normalizedString,
126                    token,
127                        language,
128                        Name,
129                            NCName,
130                                ID,
131                                IDREF,
132                                    IDREFS,
133                                ENTITY,
134                                    ENTITIES,
135                        NMTOKEN,
136                        NMTOKENS,
137            decimal,
138                integer,
139                    nonPositiveInteger,
140                        negativeInteger,
141                    long,
142                        int,
143                            short,
144                                byte,
145                    nonNegativeInteger,
146                        unsignedLong,
147                            unsignedInt,
148                                unsignedShort,
149                                    unsignedByte,
150                        positiveInteger
151    );
152}
153
154/// The standard `rdfs:` namespace.
155pub mod rdfs {
156    namespace!(
157        "http://www.w3.org/2000/01/rdf-schema#",
158        // types
159        Class,
160        Container,
161        ContainerMembershipProperty,
162        Datatype,
163        Literal,
164        Resource,
165        // semantic properties
166        domain,
167        range,
168        subClassOf,
169        subPropertyOf,
170        // documentation properties
171        comment,
172        isDefinedBy,
173        label,
174        member,
175        seeAlso
176    );
177}
178
179/// The standard `xml:` namespace
180pub mod xml {
181    namespace!(
182        "http://www.w3.org/XML/1998/namespace#",
183        lang,
184        space,
185        base,
186        id,
187        // Jon Bosak
188        Father
189    );
190}
191
192/// The standard `owl:` namespace
193pub mod owl {
194    namespace!(
195        "http://www.w3.org/2002/07/owl#",
196        Nothing,
197        Thing,
198        // Classes
199        AllDifferent,
200        AllDisjointClasses,
201        AnnotationProperty,
202        Class,
203        DatatypeProperty,
204        FunctionalProperty,
205        InverseFunctionalProperty,
206        IrreflexiveProperty,
207        ObjectProperty,
208        SymmetricProperty,
209        TransitiveProperty,
210        // Properties
211        allValuesFrom,
212        assertionProperty,
213        complementOf,
214        differentFrom,
215        disjointWith,
216        distinctMembers,
217        equivalentClass,
218        equivalentProperty,
219        intersectionOf,
220        inverseOf,
221        maxCardinality,
222        maxQualifiedCardinality,
223        members,
224        onClass,
225        oneOf,
226        onProperty,
227        propertyChainAxiom,
228        propertyDisjointWith,
229        sameAs,
230        someValuesFrom,
231        sourceIndividual,
232        targetIndividual,
233        targetValue,
234        unionOf
235    );
236}
237
238#[cfg(test)]
239mod test {
240    // Nothing really worth testing here
241    use super::*;
242    use std::rc::Rc;
243
244    #[test]
245    fn test_same_term() {
246        let ns1 = Namespace::new("http://schema.org/").unwrap();
247        let ns2 = Namespace::new(Rc::from("http://schema.org/")).unwrap();
248
249        assert_eq!(
250            ns1.get("name").unwrap().to_string(),
251            ns1.get("name").unwrap().to_string()
252        );
253        assert_eq!(
254            ns2.get("name").unwrap().to_string(),
255            ns2.get("name").unwrap().to_string()
256        );
257        assert_eq!(
258            ns1.get("name").unwrap().to_string(),
259            ns2.get("name").unwrap().to_string()
260        );
261    }
262
263    #[test]
264    fn test_different_terms() {
265        let ns1 = Namespace::new("http://schema.org/").unwrap();
266        assert_ne!(
267            ns1.get("name").unwrap().to_string(),
268            ns1.get("givenName").unwrap().to_string()
269        );
270    }
271
272    #[test]
273    fn test_invalid_namespace() {
274        assert!(Namespace::new("http://schema.org ").is_err());
275    }
276
277    #[test]
278    fn test_invalid_suffix() {
279        let ns1 = Namespace::new("http://schema.org/").unwrap();
280        assert!(ns1.get("name ").is_err());
281    }
282}