use super::expand_element;
use crate::{ActiveProperty, Error, Expanded, Loader, Options, WarningHandler};
use jsonld_context_processing::ProcessingCache;
use jsonld_core::{Context, Environment, ExpandedDocument, IndexedObject, Object};
use jstrict::Value;
use rdfx::vocabulary::VocabularyMut;
use std::hash::Hash;
pub(crate) async fn expand<'a, N, L, W>(
env: Environment<'a, N, L, W>,
document: &'a Value,
active_context: Context<N::Iri, N::BlankId>,
base_url: Option<&'a N::Iri>,
options: Options,
) -> Result<ExpandedDocument<N::Iri, N::BlankId>, Error<L::Error>>
where
N: VocabularyMut,
N::Iri: Clone + Eq + Hash,
N::BlankId: Clone + Eq + Hash,
L: Loader,
W: WarningHandler<N>,
{
fn single<T: Eq + Hash, B: Eq + Hash>(obj: IndexedObject<T, B>) -> ExpandedDocument<T, B> {
match obj.into_unnamed_graph() {
Ok(graph) => ExpandedDocument::from(graph),
Err(obj) => {
let mut result = ExpandedDocument::new();
if filter_top_level_item(&obj) {
result.insert(obj);
}
result
}
}
}
let cache = ProcessingCache::new();
let expanded = expand_element(env, &active_context, ActiveProperty::None, document, base_url, options, false, Some(&cache)).await?;
match expanded {
Expanded::Null => Ok(ExpandedDocument::new()),
Expanded::Object(obj) => Ok(single(obj)),
Expanded::Array(ary) => match <[_; 1]>::try_from(ary) {
Ok([obj]) => Ok(single(obj)),
Err(ary) => Ok(ary.into_iter().filter(filter_top_level_item).collect()),
},
}
}
pub(crate) fn filter_top_level_item<T, B>(item: &IndexedObject<T, B>) -> bool {
!matches!(item.inner(), Object::Value(_))
}