1pub use jstrict::print::{Options, Print, Printed};
8use jstrict::print::{
9 PrecomputeSize,
10 PrecomputeSizeWithContext,
11 PrintWithContext,
12 PrintWithSize,
13 PrintWithSizeAndContext,
14 Size,
15 pre_compute_array_size,
16 pre_compute_object_size,
17 print_array,
18 print_object,
19 printed_string_size,
20 string_literal,
21};
22
23use crate::{ExpandedDocument, Id, Indexed, Object, object};
24use contextual::WithContext;
25use rdfx::vocabulary::{IriVocabulary, Vocabulary};
26
27pub trait PrintWithSizeAndVocabulary<V> {
30 fn fmt_with_size_and(
36 &self,
37 vocabulary: &V,
38 f: &mut std::fmt::Formatter,
39 options: &Options,
40 indent: usize,
41 sizes: &[Size],
42 index: &mut usize,
43 ) -> std::fmt::Result;
44}
45
46impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for ExpandedDocument<T, B> {
47 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
48 pre_compute_array_size(self.objects().iter().map(|o| o.with(vocabulary)), options, sizes)
49 }
50}
51
52impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for ExpandedDocument<T, B> {
53 fn contextual_fmt_with(&self, vocabulary: &N, f: &mut std::fmt::Formatter, options: &Options, indent: usize) -> std::fmt::Result {
54 let mut sizes = Vec::with_capacity(self.count(|i| i.is_json_array() || i.is_json_object()));
55 self.contextual_pre_compute_size(vocabulary, options, &mut sizes);
56 let mut index = 0;
57 self.contextual_fmt_with_size(vocabulary, f, options, indent, &sizes, &mut index)
58 }
59}
60
61impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for object::Node<T, B> {
62 fn contextual_fmt_with(&self, vocabulary: &N, f: &mut std::fmt::Formatter, options: &Options, indent: usize) -> std::fmt::Result {
63 let mut sizes = Vec::with_capacity(self.count(|i| i.is_json_array() || i.is_json_object()));
64 self.contextual_pre_compute_size(vocabulary, options, &mut sizes);
65 let mut index = 0;
66 self.contextual_fmt_with_size(vocabulary, f, options, indent, &sizes, &mut index)
67 }
68}
69
70impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for ExpandedDocument<T, B> {
71 fn contextual_fmt_with_size(
72 &self,
73 vocabulary: &N,
74 f: &mut std::fmt::Formatter,
75 options: &Options,
76 indent: usize,
77 sizes: &[Size],
78 index: &mut usize,
79 ) -> std::fmt::Result {
80 print_array(self.objects().iter().map(|o| o.with(vocabulary)), f, options, indent, sizes, index)
81 }
82}
83
84impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for Id<T, B> {
85 fn contextual_pre_compute_size(&self, vocabulary: &N, _options: &Options, _sizes: &mut Vec<Size>) -> Size {
86 Size::Width(printed_string_size(self.with(vocabulary).as_str()))
87 }
88}
89
90impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for Id<T, B> {
91 fn contextual_fmt_with(&self, vocabulary: &N, f: &mut std::fmt::Formatter, _options: &Options, _indent: usize) -> std::fmt::Result {
92 string_literal(self.with(vocabulary).as_str(), f)
93 }
94}
95
96impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for Id<T, B> {
97 fn contextual_fmt_with_size(
98 &self,
99 vocabulary: &N,
100 f: &mut std::fmt::Formatter,
101 _options: &Options,
102 _indent: usize,
103 _sizes: &[Size],
104 _index: &mut usize,
105 ) -> std::fmt::Result {
106 string_literal(self.with(vocabulary).as_str(), f)
107 }
108}
109
110impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for Indexed<Object<T, B>> {
111 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
112 pre_compute_object_size(
113 self.entries().map(|e| {
114 let (k, v) = e.into_key_value();
115 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
116 }),
117 options,
118 sizes,
119 )
120 }
121}
122
123impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for Indexed<Object<T, B>> {
124 fn contextual_fmt_with_size(
125 &self,
126 vocabulary: &N,
127 f: &mut std::fmt::Formatter,
128 options: &Options,
129 indent: usize,
130 sizes: &[Size],
131 index: &mut usize,
132 ) -> std::fmt::Result {
133 print_object(
134 self.entries().map(|e| {
135 let (k, v) = e.into_key_value();
136 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
137 }),
138 f,
139 options,
140 indent,
141 sizes,
142 index,
143 )
144 }
145}
146
147impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::IndexedEntryValueRef<'_, T, B> {
148 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
149 match self {
150 object::IndexedEntryValueRef::Index(s) => Size::Width(printed_string_size(s)),
151 object::IndexedEntryValueRef::Object(e) => e.into_with(vocabulary).pre_compute_size(options, sizes),
152 }
153 }
154}
155
156impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::IndexedEntryValueRef<'_, T, B> {
157 fn contextual_fmt_with_size(
158 &self,
159 vocabulary: &N,
160 f: &mut std::fmt::Formatter,
161 options: &Options,
162 indent: usize,
163 sizes: &[Size],
164 index: &mut usize,
165 ) -> std::fmt::Result {
166 match self {
167 object::IndexedEntryValueRef::Index(s) => string_literal(s, f),
168 object::IndexedEntryValueRef::Object(e) => e.into_with(vocabulary).fmt_with_size(f, options, indent, sizes, index),
169 }
170 }
171}
172
173impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::EntryValueRef<'_, T, B> {
174 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
175 match self {
176 object::EntryValueRef::Value(v) => v.into_with(vocabulary).pre_compute_size(options, sizes),
177 object::EntryValueRef::List(l) => pre_compute_array_size(l.iter().map(|i| i.with(vocabulary)), options, sizes),
178 object::EntryValueRef::Node(n) => n.into_with(vocabulary).pre_compute_size(options, sizes),
179 }
180 }
181}
182
183impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::EntryValueRef<'_, T, B> {
184 fn contextual_fmt_with_size(
185 &self,
186 vocabulary: &N,
187 f: &mut std::fmt::Formatter,
188 options: &Options,
189 indent: usize,
190 sizes: &[Size],
191 index: &mut usize,
192 ) -> std::fmt::Result {
193 match self {
194 object::EntryValueRef::Value(v) => v.into_with(vocabulary).fmt_with_size(f, options, indent, sizes, index),
195 object::EntryValueRef::List(l) => print_array(l.iter().map(|i| i.with(vocabulary)), f, options, indent, sizes, index),
196 object::EntryValueRef::Node(n) => n.into_with(vocabulary).fmt_with_size(f, options, indent, sizes, index),
197 }
198 }
199}
200
201impl<T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N> for object::value::EntryRef<'_, T> {
202 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
203 match self {
204 object::value::EntryRef::Value(v) => v.pre_compute_size(options, sizes),
205 object::value::EntryRef::Type(t) => t.into_with(vocabulary).pre_compute_size(options, sizes),
206 object::value::EntryRef::Language(l) => l.pre_compute_size(options, sizes),
207 object::value::EntryRef::Direction(d) => d.pre_compute_size(options, sizes),
208 }
209 }
210}
211
212impl<T, N: IriVocabulary<Iri = T>> PrintWithSizeAndContext<N> for object::value::EntryRef<'_, T> {
213 fn contextual_fmt_with_size(
214 &self,
215 vocabulary: &N,
216 f: &mut std::fmt::Formatter,
217 options: &Options,
218 indent: usize,
219 sizes: &[Size],
220 index: &mut usize,
221 ) -> std::fmt::Result {
222 match self {
223 object::value::EntryRef::Value(v) => v.fmt_with_size(f, options, indent, sizes, index),
224 object::value::EntryRef::Type(t) => t.into_with(vocabulary).fmt_with(f, options, indent),
225 object::value::EntryRef::Language(l) => l.fmt_with(f, options, indent),
226 object::value::EntryRef::Direction(d) => d.fmt_with(f, options, indent),
227 }
228 }
229}
230
231impl<T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N> for object::value::TypeRef<'_, T> {
232 fn contextual_pre_compute_size(&self, vocabulary: &N, _options: &Options, _sizes: &mut Vec<Size>) -> Size {
233 match self {
234 object::value::TypeRef::Id(id) => Size::Width(printed_string_size(vocabulary.iri(id).map_or("<unresolved iri>", iri_rs::Iri::into_inner))),
235 object::value::TypeRef::Json => Size::Width(printed_string_size("@json")),
236 }
237 }
238}
239
240impl<T, N: IriVocabulary<Iri = T>> PrintWithContext<N> for object::value::TypeRef<'_, T> {
241 fn contextual_fmt_with(&self, vocabulary: &N, f: &mut std::fmt::Formatter, _options: &Options, _indent: usize) -> std::fmt::Result {
242 match self {
243 object::value::TypeRef::Id(id) => string_literal(vocabulary.iri(id).map_or("<unresolved iri>", iri_rs::Iri::into_inner), f),
244 object::value::TypeRef::Json => string_literal("@json", f),
245 }
246 }
247}
248
249impl PrecomputeSize for object::value::ValueEntryRef<'_> {
250 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
251 match self {
252 Self::Literal(l) => l.pre_compute_size(options, sizes),
253 Self::LangString(s) => Size::Width(printed_string_size(s)),
254 Self::Json(j) => j.pre_compute_size(options, sizes),
255 }
256 }
257}
258
259impl PrintWithSize for object::value::ValueEntryRef<'_> {
260 fn fmt_with_size(&self, f: &mut std::fmt::Formatter, options: &Options, indent: usize, sizes: &[Size], index: &mut usize) -> std::fmt::Result {
261 match self {
262 Self::Literal(l) => l.fmt_with(f, options, indent),
263 Self::LangString(s) => string_literal(s, f),
264 Self::Json(j) => j.fmt_with_size(f, options, indent, sizes, index),
265 }
266 }
267}
268
269impl PrecomputeSize for object::value::Literal {
270 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
271 match self {
272 Self::Null => Size::Width(4),
273 Self::Boolean(b) => b.pre_compute_size(options, sizes),
274 Self::Number(n) => Size::Width(n.as_str().len()),
275 Self::String(s) => Size::Width(printed_string_size(s)),
276 }
277 }
278}
279
280impl Print for object::value::Literal {
281 fn fmt_with(&self, f: &mut std::fmt::Formatter, options: &Options, indent: usize) -> std::fmt::Result {
282 match self {
283 Self::Null => write!(f, "null"),
284 Self::Boolean(b) => b.fmt_with(f, options, indent),
285 Self::Number(n) => std::fmt::Display::fmt(n, f),
286 Self::String(s) => string_literal(s, f),
287 }
288 }
289}
290
291impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::Node<T, B> {
292 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
293 pre_compute_object_size(
294 self.entries().map(|e| {
295 let (k, v) = e.into_key_value();
296 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
297 }),
298 options,
299 sizes,
300 )
301 }
302}
303
304impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::Node<T, B> {
305 fn contextual_fmt_with_size(
306 &self,
307 vocabulary: &N,
308 f: &mut std::fmt::Formatter,
309 options: &Options,
310 indent: usize,
311 sizes: &[Size],
312 index: &mut usize,
313 ) -> std::fmt::Result {
314 print_object(
315 self.entries().map(|e| {
316 let (k, v) = e.into_key_value();
317 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
318 }),
319 f,
320 options,
321 indent,
322 sizes,
323 index,
324 )
325 }
326}
327
328impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for Indexed<object::Node<T, B>> {
329 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
330 pre_compute_object_size(
331 self.entries().map(|e| {
332 let (k, v) = e.into_key_value();
333 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
334 }),
335 options,
336 sizes,
337 )
338 }
339}
340
341impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for Indexed<object::Node<T, B>> {
342 fn contextual_fmt_with_size(
343 &self,
344 vocabulary: &N,
345 f: &mut std::fmt::Formatter,
346 options: &Options,
347 indent: usize,
348 sizes: &[Size],
349 index: &mut usize,
350 ) -> std::fmt::Result {
351 print_object(
352 self.entries().map(|e| {
353 let (k, v) = e.into_key_value();
354 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
355 }),
356 f,
357 options,
358 indent,
359 sizes,
360 index,
361 )
362 }
363}
364
365impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::node::IndexedEntryValueRef<'_, T, B> {
366 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
367 match self {
368 object::node::IndexedEntryValueRef::Index(s) => Size::Width(printed_string_size(s)),
369 object::node::IndexedEntryValueRef::Node(e) => e.into_with(vocabulary).pre_compute_size(options, sizes),
370 }
371 }
372}
373
374impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::node::IndexedEntryValueRef<'_, T, B> {
375 fn contextual_fmt_with_size(
376 &self,
377 vocabulary: &N,
378 f: &mut std::fmt::Formatter,
379 options: &Options,
380 indent: usize,
381 sizes: &[Size],
382 index: &mut usize,
383 ) -> std::fmt::Result {
384 match self {
385 object::node::IndexedEntryValueRef::Index(s) => string_literal(s, f),
386 object::node::IndexedEntryValueRef::Node(e) => e.into_with(vocabulary).fmt_with_size(f, options, indent, sizes, index),
387 }
388 }
389}
390
391impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::node::EntryValueRef<'_, T, B> {
392 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
393 match *self {
394 object::node::EntryValueRef::Id(v) => v.contextual_pre_compute_size(vocabulary, options, sizes),
395 object::node::EntryValueRef::Type(v) => pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes),
396 object::node::EntryValueRef::Graph(v) => pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes),
397 object::node::EntryValueRef::Included(v) => pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes),
398 object::node::EntryValueRef::Reverse(v) => v.contextual_pre_compute_size(vocabulary, options, sizes),
399 object::node::EntryValueRef::Property(v) => pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes),
400 }
401 }
402}
403
404impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::node::EntryValueRef<'_, T, B> {
405 fn contextual_fmt_with_size(
406 &self,
407 vocabulary: &N,
408 f: &mut std::fmt::Formatter,
409 options: &Options,
410 indent: usize,
411 sizes: &[Size],
412 index: &mut usize,
413 ) -> std::fmt::Result {
414 match self {
415 object::node::EntryValueRef::Id(v) => v.with(vocabulary).fmt_with(f, options, indent),
416 object::node::EntryValueRef::Type(v) => print_array(v.iter().map(|i| i.with(vocabulary)), f, options, indent, sizes, index),
417 object::node::EntryValueRef::Graph(v) => print_array(v.iter().map(|i| i.with(vocabulary)), f, options, indent, sizes, index),
418 object::node::EntryValueRef::Included(v) => print_array(v.iter().map(|i| i.with(vocabulary)), f, options, indent, sizes, index),
419 object::node::EntryValueRef::Reverse(v) => v.contextual_fmt_with_size(vocabulary, f, options, indent, sizes, index),
420 object::node::EntryValueRef::Property(v) => print_array(v.iter().map(|i| i.with(vocabulary)), f, options, indent, sizes, index),
421 }
422 }
423}
424
425impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for object::node::ReverseProperties<T, B> {
426 fn contextual_pre_compute_size(&self, vocabulary: &N, options: &Options, sizes: &mut Vec<Size>) -> Size {
427 pre_compute_object_size(
428 self.iter().map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
429 options,
430 sizes,
431 )
432 }
433}
434
435impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::node::ReverseProperties<T, B> {
436 fn contextual_fmt_with_size(
437 &self,
438 vocabulary: &N,
439 f: &mut std::fmt::Formatter,
440 options: &Options,
441 indent: usize,
442 sizes: &[Size],
443 index: &mut usize,
444 ) -> std::fmt::Result {
445 print_object(
446 self.iter().map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
447 f,
448 options,
449 indent,
450 sizes,
451 index,
452 )
453 }
454}