use {
crate::NamespaceIRI,
std::{
fmt::{Display, Formatter},
hash::{Hash, Hasher},
},
};
#[derive(Debug, Clone)]
pub struct Namespace {
pub name: String,
pub iri: crate::TBoxNamespaceIRI,
}
impl Eq for Namespace {}
impl PartialEq for Namespace {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.iri.as_str() == other.iri.as_str()
}
}
impl Hash for Namespace {
fn hash<H: Hasher>(&self, state: &mut H) { self.name.hash(state); }
}
impl Display for Namespace {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{} <{}>", self.name.as_str(), self.iri)
}
}
impl Namespace {
pub fn declare(name: &str, iri: crate::TBoxNamespaceIRI) -> Result<Self, ekg_error::Error> {
match iri.to_string().chars().last() {
Some('/') | Some('#') => Ok(Self { name: name.to_string(), iri }),
_ => {
tracing::error!("{} does not end with either / or #", iri);
Err(ekg_error::Error::IncorrectBaseIRI { iri: iri.to_string() })
},
}
}
pub fn declare_iref_iri(name: &str, iri: &iref::Iri) -> Result<Self, ekg_error::Error> {
match iri.to_string().chars().last() {
Some('/') | Some('#') => Ok(Self { name: name.to_string(), iri: iri.try_into()? }),
_ => {
tracing::error!("{} does not end with either / or #", iri);
Err(ekg_error::Error::IncorrectBaseIRI { iri: iri.to_string() })
},
}
}
pub fn declare_from_str(name: &str, iri: &str) -> Result<Self, ekg_error::Error> {
Self::declare(name, iri.try_into()?)
}
pub fn with_local_name(
&self,
name: &str,
) -> Result<iri_string::types::IriReferenceString, ekg_error::Error> {
let iri_str = match self.iri.to_string().chars().last().unwrap() {
'/' | '#' => format!("{}{name}", self.iri),
_ => {
panic!("{} does not end with either / or #", self.iri)
},
};
Ok(iri_string::types::IriReferenceString::try_from(
iri_str,
)?)
}
#[inline]
pub fn is_in_namespace(&self, iri: &str) -> bool { self.iri.is_in_namespace(iri) }
pub fn as_sparql_prefix(&self) -> String { format!("PREFIX {} <{}>", self.name, self.iri) }
pub fn as_turtle_prefix(&self) -> String { format!("@prefix {} <{}> .", self.name, self.iri) }
}
#[cfg(test)]
mod tests {
#[test_log::test]
fn test_a_prefix() -> Result<(), ekg_error::Error> {
let namespace = crate::Namespace::declare(
"test:",
iri_string::types::IriReferenceString::try_from("http://whatever.kom/test#")
.unwrap()
.into(),
)
.unwrap();
let x = namespace.with_local_name("abc")?;
assert_eq!(
x.to_string().as_str(),
"http://whatever.kom/test#abc"
);
Ok(())
}
#[test_log::test]
fn test_b_prefix() -> Result<(), ekg_error::Error> {
let namespace = crate::Namespace::declare(
"test:",
iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/")
.unwrap()
.into(),
)
.unwrap();
let x = namespace.with_local_name("abc")?;
assert_eq!(
x.to_string().as_str(),
"http://whatever.kom/test/abc"
);
Ok(())
}
#[test_log::test]
fn test_iri_string() -> Result<(), ekg_error::Error> {
let x = iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/abc#")?;
assert_eq!(x.as_str(), "http://whatever.kom/test/abc#");
let x = iri_string::types::IriReferenceString::try_from("http://whatever.kom/test/abc/")?;
assert_eq!(x.as_str(), "http://whatever.kom/test/abc/");
Ok(())
}
}