use btree_indexmap::BTreeIndexSet;
use json_syntax::JsonValue;
use crate::{
JsonLdBacktraceBuilder, JsonLdLocatedError,
algorithms::{AsyncJsonLdEnvironment, compaction::Compactor},
syntax::JsonLdContainerItem,
};
use super::CompactFragment;
impl Compactor<'_> {
pub async fn compact_collection_with<'a, O, T>(
&self,
env: &impl AsyncJsonLdEnvironment,
items: O,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError>
where
T: 'a + CompactFragment,
O: 'a + Iterator<Item = &'a T>,
{
let mut result = Vec::new();
for (i, item) in items.enumerate() {
let item_loc = location.array_index(i);
let compacted_item = Box::pin(item.compact_fragment(env, self, item_loc)).await?;
if !compacted_item.is_null() {
result.push(compacted_item)
}
}
let mut list_or_set = false;
if let Some(active_property) = self.active_property
&& let Some(active_property_definition) = self.active_context.get(active_property)
{
list_or_set = active_property_definition
.container()
.contains(JsonLdContainerItem::List)
|| active_property_definition
.container()
.contains(JsonLdContainerItem::Set);
}
if result.is_empty()
|| result.len() > 1
|| !self.options.compact_arrays
|| self.active_property == Some("@graph")
|| self.active_property == Some("@set")
|| list_or_set
{
return Ok(JsonValue::Array(result.into_iter().collect()));
}
Ok(result.into_iter().next().unwrap())
}
}
impl<T: CompactFragment> CompactFragment for Vec<T> {
async fn compact_fragment(
&self,
env: &impl AsyncJsonLdEnvironment,
compactor: &Compactor<'_>,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError> {
compactor
.compact_collection_with(env, self.iter(), location)
.await
}
}
impl<T: CompactFragment> CompactFragment for [T] {
async fn compact_fragment(
&self,
env: &impl AsyncJsonLdEnvironment,
compactor: &Compactor<'_>,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError> {
compactor
.compact_collection_with(env, self.iter(), location)
.await
}
}
impl<T: CompactFragment> CompactFragment for BTreeIndexSet<T> {
async fn compact_fragment(
&self,
env: &impl AsyncJsonLdEnvironment,
compactor: &Compactor<'_>,
location: JsonLdBacktraceBuilder<'_>,
) -> Result<JsonValue, JsonLdLocatedError> {
compactor
.compact_collection_with(env, self.iter(), location)
.await
}
}