use json_syntax::{JsonObject, JsonValue};
use mown::Mown;
use crate::{
JsonLdBacktraceBuilder, JsonLdLocatedError, JsonLdTerm,
algorithms::{
AsyncJsonLdEnvironment, AsyncProcessingEnvironmentRef, compaction::CompactIndexedFragment,
context_processing::JsonLdContextProcessingOptions,
},
object::{AnyJsonLdObject, JsonLdObjectRef},
syntax::{JsonLdContainerItem, JsonLdKeyword},
};
use super::Compactor;
mod node;
mod value;
impl Compactor<'_> {
pub async fn compact_any_indexed_object(
&self,
env: &impl AsyncJsonLdEnvironment,
object: &impl AnyJsonLdObject,
index: Option<&str>,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError> {
match object.as_ref() {
JsonLdObjectRef::Value(value) => {
self.compact_indexed_value_with(env, value, index, location)
.await
}
JsonLdObjectRef::Node(node) => {
self.compact_indexed_node_with(env, node, index, location)
.await
}
JsonLdObjectRef::List(list) => {
let mut active_context = self.active_context;
if let Some(previous_context) = active_context.previous_context() {
active_context = previous_context
}
let mut active_context = Mown::Borrowed(active_context);
let mut list_container = false;
if let Some(active_property) = self.active_property
&& let Some(active_property_definition) =
self.type_scoped_context.get(active_property)
{
if let Some(local_context) = active_property_definition.context() {
let def_loc = location.push_backtrace(
active_property_definition.location().unwrap_or_default(),
);
let scoped_context_loc = def_loc.object_value(JsonLdKeyword::Context);
active_context = Mown::Owned(
local_context
.process_with(
AsyncProcessingEnvironmentRef(env),
active_property_definition.base_url(),
active_context.as_ref(),
JsonLdContextProcessingOptions::from(self.options)
.with_override(),
scoped_context_loc,
)
.await?
.into_raw(),
)
}
list_container = active_property_definition
.container()
.contains(JsonLdContainerItem::List);
}
let list_loc = location.object_entry("@list");
if list_container {
self.with_active_context(&active_context)
.with_type_scoped_context(&active_context)
.compact_collection_with(env, list.iter(), list_loc)
.await
} else {
let mut result = JsonObject::default();
self.with_active_context(&active_context)
.compact_property(
env,
&mut result,
JsonLdTerm::Keyword(JsonLdKeyword::List),
list,
false,
list_loc,
)
.await?;
if let Some(index) = index {
let mut index_container = false;
if let Some(active_property) = self.active_property
&& let Some(active_property_definition) =
active_context.get(active_property)
&& active_property_definition
.container()
.contains(JsonLdContainerItem::Index)
{
index_container = true;
}
if !index_container {
let alias = self.with_active_context(&active_context).compact_key(
&JsonLdTerm::Keyword(JsonLdKeyword::Index),
true,
false,
location,
)?;
result.insert(alias.unwrap(), JsonValue::String(index.into()));
}
}
Ok(JsonValue::Object(result))
}
}
}
}
}
impl<T: AnyJsonLdObject> CompactIndexedFragment for T {
async fn compact_indexed_fragment(
&self,
env: &impl AsyncJsonLdEnvironment,
compactor: &Compactor<'_>,
index: Option<&str>,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError> {
compactor
.compact_any_indexed_object(env, self, index, location)
.await
}
}