mod container;
mod definition;
mod embed;
pub mod inverse;
pub use container::JsonLdContainer;
use langtag::{LangTag, LangTagBuf};
use crate::syntax::context::JsonLdContextTerm;
use crate::syntax::{JsonLdContext, JsonLdKeywordType};
use crate::{JsonLdDirection, JsonLdLenient, JsonLdTerm};
use rdf_syntax::{Iri, IriBuf};
use std::borrow::{Borrow, Cow};
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use std::sync::OnceLock;
pub use definition::*;
pub use embed::*;
pub use inverse::InverseJsonLdContext;
pub struct JsonLdProcessedContext<'a> {
unprocessed: Cow<'a, JsonLdContext>,
raw: RawJsonLdProcessedContext,
}
impl<'a> JsonLdProcessedContext<'a> {
pub fn new(unprocessed: Cow<'a, JsonLdContext>, raw: RawJsonLdProcessedContext) -> Self {
Self { unprocessed, raw }
}
pub fn unprocessed(&self) -> &JsonLdContext {
&self.unprocessed
}
pub fn as_raw(&self) -> &RawJsonLdProcessedContext {
&self.raw
}
pub fn into_raw(self) -> RawJsonLdProcessedContext {
self.raw
}
pub fn into_owned(self) -> JsonLdProcessedContext<'static> {
JsonLdProcessedContext {
unprocessed: Cow::Owned(self.unprocessed.into_owned()),
raw: self.raw,
}
}
}
impl Deref for JsonLdProcessedContext<'_> {
type Target = RawJsonLdProcessedContext;
fn deref(&self) -> &Self::Target {
&self.raw
}
}
impl DerefMut for JsonLdProcessedContext<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.raw
}
}
#[derive(Default)]
pub struct RawJsonLdProcessedContext {
original_base_url: Option<IriBuf>,
base_iri: Option<IriBuf>,
vocabulary: Option<JsonLdTerm>,
default_language: Option<JsonLdLenient<LangTagBuf>>,
default_base_direction: Option<JsonLdDirection>,
previous_context: Option<Box<Self>>,
definitions: JsonLdDefinitions,
inverse: OnceLock<InverseJsonLdContext>,
}
pub type DefinitionEntryRef<'a> = (&'a JsonLdContextTerm, &'a JsonLdProcessedTermDefinition);
impl RawJsonLdProcessedContext {
pub fn new(base_iri: Option<IriBuf>) -> Self {
Self {
original_base_url: base_iri.clone(),
base_iri,
vocabulary: None,
default_language: None,
default_base_direction: None,
previous_context: None,
definitions: JsonLdDefinitions::default(),
inverse: OnceLock::default(),
}
}
pub fn get<Q>(&self, term: &Q) -> Option<JsonLdProcessedTermDefinitionRef<'_>>
where
JsonLdContextTerm: Borrow<Q>,
JsonLdKeywordType: Borrow<Q>,
Q: ?Sized + Hash + Eq,
{
self.definitions.get(term)
}
pub fn get_normal<Q>(&self, term: &Q) -> Option<&JsonLdProcessedNormalTermDefinition>
where
JsonLdContextTerm: Borrow<Q>,
Q: ?Sized + Hash + Eq,
{
self.definitions.get_normal(term)
}
pub fn get_type(&self) -> Option<&JsonLdProcessedTypeTermDefinition> {
self.definitions.get_type()
}
pub fn contains_term<Q>(&self, term: &Q) -> bool
where
JsonLdContextTerm: Borrow<Q>,
JsonLdKeywordType: Borrow<Q>,
Q: ?Sized + Hash + Eq,
{
self.definitions.contains_term(term)
}
pub fn original_base_url(&self) -> Option<&Iri> {
self.original_base_url.as_deref()
}
pub fn base_iri(&self) -> Option<&Iri> {
self.base_iri.as_deref()
}
pub fn vocabulary(&self) -> Option<&JsonLdTerm> {
match &self.vocabulary {
Some(v) => Some(v),
None => None,
}
}
pub fn default_language(&self) -> Option<JsonLdLenient<&LangTag>> {
self.default_language.as_ref().map(|tag| tag.as_deref())
}
pub fn default_base_direction(&self) -> Option<JsonLdDirection> {
self.default_base_direction
}
pub fn previous_context(&self) -> Option<&Self> {
match &self.previous_context {
Some(c) => Some(c),
None => None,
}
}
pub fn len(&self) -> usize {
self.definitions.len()
}
pub fn is_empty(&self) -> bool {
self.definitions.is_empty()
}
pub fn definitions(&self) -> &JsonLdDefinitions {
&self.definitions
}
pub fn has_protected_items(&self) -> bool {
for binding in self.definitions() {
if binding.definition().protected() {
return true;
}
}
false
}
pub fn inverse(&self) -> &InverseJsonLdContext {
self.inverse.get_or_init(|| self.into())
}
pub fn set_normal(
&mut self,
key: JsonLdContextTerm,
definition: Option<JsonLdProcessedNormalTermDefinition>,
) -> Option<JsonLdProcessedNormalTermDefinition> {
self.inverse.take();
self.definitions.set_normal(key, definition)
}
pub fn set_type(
&mut self,
type_: Option<JsonLdProcessedTypeTermDefinition>,
) -> Option<JsonLdProcessedTypeTermDefinition> {
self.definitions.set_type(type_)
}
pub fn set_base_iri(&mut self, iri: Option<IriBuf>) {
self.inverse.take();
self.base_iri = iri
}
pub fn set_vocabulary(&mut self, vocab: Option<JsonLdTerm>) {
self.inverse.take();
self.vocabulary = vocab;
}
pub fn set_default_language(&mut self, lang: Option<JsonLdLenient<LangTagBuf>>) {
self.inverse.take();
self.default_language = lang;
}
pub fn set_default_base_direction(&mut self, dir: Option<JsonLdDirection>) {
self.inverse.take();
self.default_base_direction = dir;
}
pub fn set_previous_context(&mut self, previous: Self) {
self.inverse.take();
self.previous_context = Some(Box::new(previous))
}
}
impl Clone for RawJsonLdProcessedContext {
fn clone(&self) -> Self {
Self {
original_base_url: self.original_base_url.clone(),
base_iri: self.base_iri.clone(),
vocabulary: self.vocabulary.clone(),
default_language: self.default_language.clone(),
default_base_direction: self.default_base_direction,
previous_context: self.previous_context.clone(),
definitions: self.definitions.clone(),
inverse: OnceLock::default(),
}
}
}
impl PartialEq for RawJsonLdProcessedContext {
fn eq(&self, other: &Self) -> bool {
self.original_base_url == other.original_base_url
&& self.base_iri == other.base_iri
&& self.vocabulary == other.vocabulary
&& self.default_language == other.default_language
&& self.default_base_direction == other.default_base_direction
&& self.previous_context == other.previous_context
}
}