use crate::{
LocalName,
iri::{Iri, IriExtra},
pname::Namespace,
vocab::{
VOCABULARY_OWL, VOCABULARY_RDF, VOCABULARY_RDF_SCHEMA, VOCABULARY_XML_SCHEMA, Vocabulary,
},
};
use bimap::BiBTreeMap;
use std::fmt::Display;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct IriPrefixMap {
map: BiBTreeMap<Namespace, Iri>,
}
impl Display for IriPrefixMap {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Prefixes(")?;
for (prefix, iri) in &self.map {
writeln!(f, " {prefix} {iri} ,")?;
}
writeln!(f, ")")
}
}
impl IriPrefixMap {
pub fn common() -> Self {
Self::default()
.with_vocabulary(&VOCABULARY_RDF)
.with_vocabulary(&VOCABULARY_RDF_SCHEMA)
.with_vocabulary(&VOCABULARY_XML_SCHEMA)
.with_vocabulary(&VOCABULARY_OWL)
}
pub fn with_default(mut self, iri: Iri) -> Self {
self.set_default_namespace(iri);
self
}
pub fn with(mut self, prefix: Namespace, iri: Iri) -> Self {
self.insert(prefix, iri);
self
}
pub fn with_vocabulary(self, vocabulary: &Vocabulary) -> Self {
Self::with(
self,
vocabulary.prefix_as_namespace(),
vocabulary.iri_as_iri(),
)
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn get_default_namespace(&self) -> Option<&Iri> {
self.map.get_by_left(&Namespace::new_default())
}
pub fn set_default_namespace(&mut self, iri: Iri) {
let _ = self.map.insert(Namespace::new_default(), iri);
}
pub fn remove_default_namespace(&mut self) {
let _ = self.map.remove_by_left(&Namespace::new_default());
}
pub fn get_namespace(&self, prefix: &Namespace) -> Option<&Iri> {
self.map.get_by_left(prefix)
}
pub fn get_prefix(&self, namespace: &Iri) -> Option<&Namespace> {
self.map.get_by_right(namespace)
}
pub fn mappings(&self) -> impl Iterator<Item = (&Namespace, &Iri)> {
self.map.iter()
}
pub fn prefixes(&self) -> impl Iterator<Item = &Namespace> {
self.map.left_values()
}
pub fn iris(&self) -> impl Iterator<Item = &Iri> {
self.map.right_values()
}
pub fn insert(&mut self, prefix: Namespace, iri: Iri) {
let _ = self.map.insert(prefix, iri);
}
pub fn insert_vocabulary(&mut self, vocabulary: &Vocabulary) {
self.insert(vocabulary.prefix_as_namespace(), vocabulary.iri_as_iri());
}
pub fn remove(&mut self, prefix: &Namespace) {
let _ = self.map.remove_by_left(prefix);
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn expand(&self, local_name: &LocalName) -> Option<Iri> {
match self
.get_namespace(local_name.namespace())
.map(|ns| ns.make_name(local_name.name().clone()))
{
Some(expanded) => expanded,
None => None,
}
}
pub fn compress(&self, iri: &Iri) -> Option<LocalName> {
let (iri, name) = if let Some((iri, name)) = iri.split() {
(iri, name)
} else {
return None;
};
match self.get_prefix(&iri) {
None => None,
Some(prefix) => Some(LocalName::new(prefix.clone(), name)),
}
}
}