1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
mod expanded;
mod iri;
mod literal;
mod value;
mod node;
mod array;
mod element;
use std::cmp::{Ord, Ordering};
use std::collections::HashSet;
use futures::Future;
use iref::{Iri, IriBuf};
use json::JsonValue;
use crate::{
ProcessingMode,
Error,
Id,
Indexed,
Object,
ContextMut,
context::{
ProcessingOptions,
Loader
}
};
pub use expanded::*;
pub use iri::*;
pub use literal::*;
pub use value::*;
pub use node::*;
pub use array::*;
pub use element::*;
#[derive(Clone, Copy, Default)]
pub struct Options {
pub processing_mode: ProcessingMode,
pub ordered: bool
}
impl From<Options> for ProcessingOptions {
fn from(options: Options) -> ProcessingOptions {
let mut copt = ProcessingOptions::default();
copt.processing_mode = options.processing_mode;
copt
}
}
#[derive(PartialEq, Eq)]
pub struct Entry<'a, T>(T, &'a JsonValue);
impl<'a, T: PartialOrd> PartialOrd for Entry<'a, T> {
fn partial_cmp(&self, other: &Entry<'a, T>) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<'a, T: Ord> Ord for Entry<'a, T> {
fn cmp(&self, other: &Entry<'a, T>) -> Ordering {
self.0.cmp(&other.0)
}
}
fn filter_top_level_item<T: Id>(item: &Indexed<Object<T>>) -> bool {
match item.inner() {
Object::Value(_) => false,
_ => true
}
}
pub fn expand<'a, T: Send + Sync + Id, C: Send + Sync + ContextMut<T>, L: Send + Sync + Loader>(active_context: &'a C, element: &'a JsonValue, base_url: Option<Iri>, loader: &'a mut L, options: Options) -> impl 'a + Send + Future<Output=Result<HashSet<Indexed<Object<T>>>, Error>> where C::LocalContext: Send + Sync + From<L::Output> + From<JsonValue>, L::Output: Into<JsonValue> {
let base_url = base_url.map(|url| IriBuf::from(url));
async move {
let base_url = base_url.as_ref().map(|url| url.as_iri());
let expanded = expand_element(active_context, None, element, base_url, loader, options).await?;
if expanded.len() == 1 {
match expanded.into_iter().next().unwrap().into_unnamed_graph() {
Ok(graph) => Ok(graph),
Err(obj) => {
let mut set = HashSet::new();
if filter_top_level_item(&obj) {
set.insert(obj);
}
Ok(set)
}
}
} else {
Ok(expanded.into_iter().filter(filter_top_level_item).collect())
}
}
}