1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
/*! ![names](https://img.shields.io/badge/RDFtk-names-BD1B89?logo=data:image/png;base64,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) This crate provides a set of modules that contain the `IRI`s and `QName` strings for commonly used vocabularies. It also provides macro support for defining new namespaces in the same style as this library. The vocabularies supported can be found [below](#modules). # Macro Example The following example replicates the `geo` module using the `namespace!` macro. Note that as this macro uses `paste::item` the client will need to have a dependency on the [paste crate](https://crates.io/crates/paste). ```rust,ignore #[macro_use] extern crate paste; #[macro_use] extern crate rdftk_names; use rdftk_names::Vocabulary; namespace! { GeoSpatialVocabulary, "geo", "http://www.w3.org/2003/01/geo/wgs84_pos#", { spatial_thing, "SpatialThing", temporal_thing, "TemporalThing", event, "Event", point, "Point", lat, "lat", location, "location", long, "long", alt, "alt", lat_long, "lat_long" } } ``` */ #![warn( // ---------- Stylistic future_incompatible, nonstandard_style, rust_2018_idioms, trivial_casts, trivial_numeric_casts, // ---------- Public missing_debug_implementations, missing_docs, unreachable_pub, // ---------- Unsafe unsafe_code, // ---------- Unused unused_extern_crates, unused_import_braces, unused_qualifications, unused_results, )] #[allow(unused_imports)] #[macro_use] extern crate lazy_static; #[allow(unused_imports)] #[macro_use] extern crate paste; // ------------------------------------------------------------------------------------------------ // Macros // ------------------------------------------------------------------------------------------------ /// /// This macro produces the constants and functions to describe a vocabulary. It creates the /// following items. /// /// 1. An identifier for the vocabulary struct. /// 1. A constant, `PREFIX` that contains the string passed in the `$prefix` parameter. /// 1. A constant, `NAMESPACE` that contains the string passed in the `namespace` parameter. /// 1. For each pair of `$fn_name`, `$name` (assuming `foo` and `"Foo"`): /// 1. create a function `fn foo() -> IRI` that returns the name as a full IRI. This concatenates /// `NAMESPACE` and `$name`. /// 1. create a function `fn foo_qname() -> String` that returns a qualified name String. This /// concatenates the `PREFIX`, `":"`, and `$name`. /// /// # Example /// /// Given the following namespace invocation, /// /// ```rust,ignore /// #[macro_use] /// extern crate rdftk_names; /// /// namespace!(FooBarVocab, "fb", "http://example.com/schema/FooBar#", { foo, "Foo" } ); /// ``` /// /// The following would be generated. /// /// ```rust, ignore /// use rdftk_iri::IRI; /// use std::str::FromStr; /// /// pub struct FooBarVocab { ... } /// /// impl Default for FooBarVocab { ... } /// /// impl Vocabulary for FooBarVocab { ... } /// /// impl FooBarVocab { /// pub fn foo(&self) -> &Arc<IRI> { ... } /// pub foo_qname(&self) -> &String { ... } /// } /// ``` /// #[macro_export] macro_rules! namespace { ($prefix:expr, $namespace:expr, { $($fn_name:ident, $name:expr),* }) => { use rdftk_iri::{IRI, IRIRef}; use std::str::FromStr; use std::collections::HashMap; const PREFIX: &str = $prefix; const NAMESPACE: &str = $namespace; lazy_static! { static ref NS_IRI: IRIRef = IRIRef::new(NAMESPACE.parse().unwrap()); static ref NS_CACHE: HashMap<String, (IRIRef, String)> = make_cache(); } fn make_cache() -> HashMap<String, (IRIRef, String)> { let mut cache: HashMap<String, (IRIRef, String)> = Default::default(); $( let _ = cache.insert($name.to_string(), ( IRIRef::new(IRI::from_str(&format!("{}{}", NAMESPACE, $name)).unwrap()), format!("{}:{}", PREFIX, $name), ) ); )* cache } #[inline] #[doc = "Returns the commonly used prefix for this namespace."] pub fn default_prefix() -> &'static str { PREFIX } #[inline] #[doc = "Returns the IRI, as a string, for this namespace."] pub fn namespace_str() -> &'static str { NAMESPACE } #[inline] #[doc = "Returns the IRI for this namespace."] pub fn namespace_iri() -> &'static IRIRef { &NS_IRI } $( nsname!($fn_name, $name); )* }; } /// /// This macro *should only* called by the `namespace!` macro. It takes an identifier and a /// string and produces: /// /// 1. a function with the same identifier which returns a complete IRI using the /// value of `NAMESPACE` in the current scope, and /// 1. a function with the same identifier, but the suffix `_qname` which returns a qualified name /// using the value of `PREFIX` in the current scope. /// #[macro_export] macro_rules! nsname { ($fn_name:ident, $name:expr) => { #[inline] #[doc = "Returns the IRI for this namespace member."] pub fn $fn_name() -> &'static IRIRef { &NS_CACHE.get($name).unwrap().0 } paste::item! { #[inline] #[doc = "Returns a qname, using the default prefix, for this namespace member."] pub fn [<$fn_name _qname>]() -> &'static String { &NS_CACHE.get($name).unwrap().1 } } }; } // ------------------------------------------------------------------------------------------------ // Modules // ------------------------------------------------------------------------------------------------ pub mod dc; pub mod foaf; pub mod geo; pub mod owl; pub mod rdf; pub mod rdfs; pub mod xsd; // ------------------------------------------------------------------------------------------------ // Unit Tests // ------------------------------------------------------------------------------------------------ #[cfg(test)] mod tests { #![allow(unreachable_pub)] use super::*; namespace!("p", "heep://schema/com/p#", { foo, "Foo", bar, "Bar" } ); #[test] fn test_expansion() { assert_eq!(default_prefix(), "p".to_string()); assert_eq!(namespace_str(), "heep://schema/com/p#"); assert_eq!( namespace_iri(), &IRIRef::new(IRI::from_str("heep://schema/com/p#").unwrap()) ); assert_eq!(foo().to_string(), "heep://schema/com/p#Foo"); assert_eq!(foo_qname(), "p:Foo"); assert_eq!(bar().to_string(), "heep://schema/com/p#Bar"); assert_eq!(bar_qname(), "p:Bar"); } }