ekg_identifier/
namespace.rs1use {
2 crate::NamespaceIRI,
3 std::{
4 fmt::{Display, Formatter},
5 hash::{Hash, Hasher},
6 },
7};
8
9#[derive(Debug, Clone)]
18pub struct Namespace {
19 pub name: String,
21 pub iri: crate::TBoxNamespaceIRI,
23}
24
25impl Eq for Namespace {}
26
27impl PartialEq for Namespace {
28 fn eq(&self, other: &Self) -> bool {
29 self.name == other.name && self.iri.as_str() == other.iri.as_str()
30 }
31}
32
33impl Hash for Namespace {
34 fn hash<H: Hasher>(&self, state: &mut H) { self.name.hash(state); }
35}
36
37impl Display for Namespace {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 write!(f, "{} <{}>", self.name.as_str(), self.iri)
41 }
42}
43
44impl Namespace {
45 pub fn declare(name: &str, iri: crate::TBoxNamespaceIRI) -> Result<Self, ekg_error::Error> {
46 match iri.to_string().chars().last() {
47 Some('/') | Some('#') => Ok(Self { name: name.to_string(), iri }),
48 _ => {
49 tracing::error!("{} does not end with either / or #", iri);
50 Err(ekg_error::Error::IncorrectBaseIRI { iri: iri.to_string() })
51 },
52 }
53 }
54
55 pub fn declare_iref_iri(name: &str, iri: &iref::Iri) -> Result<Self, ekg_error::Error> {
59 match iri.to_string().chars().last() {
60 Some('/') | Some('#') => Ok(Self { name: name.to_string(), iri: iri.try_into()? }),
61 _ => {
62 tracing::error!("{} does not end with either / or #", iri);
63 Err(ekg_error::Error::IncorrectBaseIRI { iri: iri.to_string() })
64 },
65 }
66 }
67
68 pub fn declare_from_str(name: &str, iri: &str) -> Result<Self, ekg_error::Error> {
69 Self::declare(name, iri.try_into()?)
70 }
71
72 pub fn with_local_name(
76 &self,
77 name: &str,
78 ) -> Result<iri_string::types::IriReferenceString, ekg_error::Error> {
79 let iri_str = match self.iri.to_string().chars().last().unwrap() {
80 '/' | '#' => format!("{}{name}", self.iri),
81 _ => {
82 panic!("{} does not end with either / or #", self.iri)
83 },
84 };
85
86 Ok(iri_string::types::IriReferenceString::try_from(
87 iri_str,
88 )?)
89 }
90
91 #[inline]
92 pub fn is_in_namespace(&self, iri: &str) -> bool { self.iri.is_in_namespace(iri) }
93
94 #[cfg(all(feature = "rdftk-support", not(target_arch = "wasm32")))]
95 pub fn as_rdftk_iri_ref(&self) -> Result<rdftk_iri::IRIRef, rdftk_iri::error::Error> {
96 Ok(rdftk_iri::IRIRef::new(self.as_rdftk_iri()?))
97 }
98
99 #[cfg(all(feature = "rdftk-support", not(target_arch = "wasm32")))]
100 pub fn as_rdftk_iri(&self) -> Result<rdftk_iri::IRI, rdftk_iri::error::Error> {
101 use std::str::FromStr;
102 rdftk_iri::IRI::from_str(self.iri.as_str())
103 }
104
105 pub fn as_sparql_prefix(&self) -> String { format!("PREFIX {} <{}>", self.name, self.iri) }
107
108 pub fn as_turtle_prefix(&self) -> String { format!("@prefix {} <{}> .", self.name, self.iri) }
110}
111
112#[cfg(test)]
113mod tests {
114 #[test_log::test]
115 fn test_a_prefix() -> Result<(), ekg_error::Error> {
116 let namespace = crate::Namespace::declare(
117 "test:",
118 iri_string::types::IriReferenceString::try_from("http://whatever.kom/test#")
119 .unwrap()
120 .try_into()
121 .unwrap(),
122 )
123 .unwrap();
124 let x = namespace.with_local_name("abc")?;
125
126 assert_eq!(
127 x.to_string().as_str(),
128 "http://whatever.kom/test#abc"
129 );
130 Ok(())
131 }
132
133 #[test_log::test]
134 fn test_b_prefix() -> Result<(), ekg_error::Error> {
135 let namespace = crate::Namespace::declare(
136 "test:",
137 iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/")
138 .unwrap()
139 .try_into()
140 .unwrap(),
141 )
142 .unwrap();
143 let x = namespace.with_local_name("abc")?;
144
145 assert_eq!(
146 x.to_string().as_str(),
147 "http://whatever.kom/test/abc"
148 );
149 Ok(())
150 }
151
152 #[test_log::test]
153 fn test_iri_string() -> Result<(), ekg_error::Error> {
154 let x = iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/abc#")?;
155 assert_eq!(x.as_str(), "http://whatever.kom/test/abc#");
156
157 let x = iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/abc/")?;
158 assert_eq!(x.as_str(), "http://whatever.kom/test/abc/");
159 Ok(())
160 }
161}