json_ld/algorithms/compaction/
mod.rs1mod collection;
5mod document;
6mod iri;
7mod object;
8mod options;
9
10use json_syntax::{JsonObject, JsonValue};
11pub use options::*;
12
13use crate::{
14 JsonLdBacktraceBuilder, JsonLdIndexed, JsonLdLocatedError, JsonLdProcessedContext, JsonLdTerm,
15 algorithms::AsyncJsonLdEnvironment,
16 context::{
17 RawJsonLdProcessedContext,
18 inverse::{JsonLdLangSelection, JsonLdTypeSelection},
19 },
20 syntax::JsonLdKeyword,
21};
22
23pub trait JsonLdCompact {
25 #[allow(async_fn_in_trait)]
27 async fn compact_with(
28 &self,
29 env: impl AsyncJsonLdEnvironment,
30 context: &JsonLdProcessedContext<'_>,
31 options: JsonLdCompactionOptions,
32 location: JsonLdBacktraceBuilder<'_>,
33 ) -> Result<JsonValue, JsonLdLocatedError>;
34
35 #[allow(async_fn_in_trait)]
37 async fn compact(
38 &self,
39 env: impl AsyncJsonLdEnvironment,
40 context: &JsonLdProcessedContext<'_>,
41 location: JsonLdBacktraceBuilder<'_>,
42 ) -> Result<JsonValue, JsonLdLocatedError> {
43 self.compact_with(env, context, JsonLdCompactionOptions::default(), location)
44 .await
45 }
46}
47
48impl<T: JsonLdCompact> JsonLdCompact for std::sync::Arc<T> {
49 async fn compact_with(
50 &self,
51 env: impl AsyncJsonLdEnvironment,
52 context: &JsonLdProcessedContext<'_>,
53 options: JsonLdCompactionOptions,
54 location: JsonLdBacktraceBuilder<'_>,
55 ) -> Result<JsonValue, JsonLdLocatedError> {
56 T::compact_with(self, env, context, options, location).await
57 }
58
59 async fn compact(
60 &self,
61 env: impl AsyncJsonLdEnvironment,
62 context: &JsonLdProcessedContext<'_>,
63 location: JsonLdBacktraceBuilder<'_>,
64 ) -> Result<JsonValue, JsonLdLocatedError> {
65 T::compact(self, env, context, location).await
66 }
67}
68
69struct Compactor<'a> {
71 pub options: JsonLdCompactionOptions,
72 pub active_context: &'a RawJsonLdProcessedContext,
73 pub type_scoped_context: &'a RawJsonLdProcessedContext,
74 pub active_property: Option<&'a str>,
75}
76
77impl Compactor<'_> {
78 fn wrap_in_graph(&self, compact: JsonValue) -> Result<JsonValue, JsonLdLocatedError> {
85 let JsonValue::Array(array) = compact else {
86 return Ok(compact);
87 };
88
89 let mut obj = JsonObject::new();
90
91 if !array.is_empty() {
92 let key = self.compact_iri(
94 &JsonLdTerm::Keyword(JsonLdKeyword::Graph),
95 true,
96 false,
97 JsonLdBacktraceBuilder::Root,
98 )?;
99
100 obj.insert(key.unwrap(), array.into());
101 }
102
103 Ok(obj.into())
104 }
105}
106
107impl<'a> Compactor<'a> {
108 pub fn new(
109 active_context: &'a RawJsonLdProcessedContext,
110 options: JsonLdCompactionOptions,
111 ) -> Self {
112 Self {
113 options,
114 active_context,
115 type_scoped_context: active_context,
116 active_property: None,
117 }
118 }
119
120 pub fn with_active_context<'b>(
121 &'b self,
122 active_context: &'b RawJsonLdProcessedContext,
123 ) -> Compactor<'b> {
124 Compactor {
125 options: self.options,
126 active_context,
127 type_scoped_context: self.type_scoped_context,
128 active_property: self.active_property,
129 }
130 }
131
132 pub fn with_type_scoped_context<'b>(
133 &'b self,
134 type_scoped_context: &'b RawJsonLdProcessedContext,
135 ) -> Compactor<'b> {
136 Compactor {
137 options: self.options,
138 active_context: self.active_context,
139 type_scoped_context,
140 active_property: self.active_property,
141 }
142 }
143
144 pub fn with_active_property<'b>(&'b self, active_property: Option<&'b str>) -> Compactor<'b> {
145 Compactor {
146 options: self.options,
147 active_context: self.active_context,
148 type_scoped_context: self.type_scoped_context,
149 active_property,
150 }
151 }
152}
153
154trait CompactFragment {
155 #[allow(async_fn_in_trait)]
156 async fn compact_fragment(
157 &self,
158 env: &impl AsyncJsonLdEnvironment,
159 compactor: &Compactor,
160 location: JsonLdBacktraceBuilder<'_>,
161 ) -> Result<JsonValue, JsonLdLocatedError>;
162}
163
164enum TypeLangValue<'a> {
165 Type(JsonLdTypeSelection),
166 Lang(JsonLdLangSelection<'a>),
167}
168
169trait CompactIndexedFragment {
171 #[allow(async_fn_in_trait)]
172 #[allow(clippy::too_many_arguments)]
173 async fn compact_indexed_fragment(
174 &self,
175 env: &impl AsyncJsonLdEnvironment,
176 compactor: &Compactor<'_>,
177 index: Option<&str>,
178 location: JsonLdBacktraceBuilder<'_>,
179 ) -> Result<JsonValue, JsonLdLocatedError>;
180}
181
182impl<T: CompactIndexedFragment> CompactFragment for JsonLdIndexed<T> {
183 async fn compact_fragment(
184 &self,
185 env: &impl AsyncJsonLdEnvironment,
186 compactor: &Compactor<'_>,
187 location: JsonLdBacktraceBuilder<'_>,
188 ) -> Result<JsonValue, JsonLdLocatedError> {
189 self.inner()
190 .compact_indexed_fragment(env, compactor, self.index(), location)
191 .await
192 }
193}