1use json_syntax::print::{
2 pre_compute_array_size, pre_compute_object_size, print_array, print_object,
3 printed_string_size, string_literal, PrecomputeSize, PrecomputeSizeWithContext,
4 PrintWithContext, PrintWithSize, PrintWithSizeAndContext, Size,
5};
6pub use json_syntax::print::{Options, Print, Printed};
7
8use crate::{object, ExpandedDocument, Id, Indexed, Object};
9use contextual::WithContext;
10use rdf_types::vocabulary::{IriVocabulary, Vocabulary};
11
12pub trait PrintWithSizeAndVocabulary<V> {
13 fn fmt_with_size_and(
14 &self,
15 vocabulary: &V,
16 f: &mut std::fmt::Formatter,
17 options: &Options,
18 indent: usize,
19 sizes: &[Size],
20 index: &mut usize,
21 ) -> std::fmt::Result;
22}
23
24impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
25 for ExpandedDocument<T, B>
26{
27 fn contextual_pre_compute_size(
28 &self,
29 vocabulary: &N,
30 options: &Options,
31 sizes: &mut Vec<Size>,
32 ) -> Size {
33 pre_compute_array_size(
34 self.objects().iter().map(|o| o.with(vocabulary)),
35 options,
36 sizes,
37 )
38 }
39}
40
41impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for ExpandedDocument<T, B> {
42 fn contextual_fmt_with(
43 &self,
44 vocabulary: &N,
45 f: &mut std::fmt::Formatter,
46 options: &Options,
47 indent: usize,
48 ) -> std::fmt::Result {
49 let mut sizes = Vec::with_capacity(self.count(|i| i.is_json_array() || i.is_json_object()));
50 self.contextual_pre_compute_size(vocabulary, options, &mut sizes);
51 let mut index = 0;
52 self.contextual_fmt_with_size(vocabulary, f, options, indent, &sizes, &mut index)
53 }
54}
55
56impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for object::Node<T, B> {
57 fn contextual_fmt_with(
58 &self,
59 vocabulary: &N,
60 f: &mut std::fmt::Formatter,
61 options: &Options,
62 indent: usize,
63 ) -> std::fmt::Result {
64 let mut sizes = Vec::with_capacity(self.count(|i| i.is_json_array() || i.is_json_object()));
65 self.contextual_pre_compute_size(vocabulary, options, &mut sizes);
66 let mut index = 0;
67 self.contextual_fmt_with_size(vocabulary, f, options, indent, &sizes, &mut index)
68 }
69}
70
71impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
72 for ExpandedDocument<T, B>
73{
74 fn contextual_fmt_with_size(
75 &self,
76 vocabulary: &N,
77 f: &mut std::fmt::Formatter,
78 options: &Options,
79 indent: usize,
80 sizes: &[Size],
81 index: &mut usize,
82 ) -> std::fmt::Result {
83 print_array(
84 self.objects().iter().map(|o| o.with(vocabulary)),
85 f,
86 options,
87 indent,
88 sizes,
89 index,
90 )
91 }
92}
93
94impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N> for Id<T, B> {
95 fn contextual_pre_compute_size(
96 &self,
97 vocabulary: &N,
98 _options: &Options,
99 _sizes: &mut Vec<Size>,
100 ) -> Size {
101 Size::Width(printed_string_size(self.with(vocabulary).as_str()))
102 }
103}
104
105impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithContext<N> for Id<T, B> {
106 fn contextual_fmt_with(
107 &self,
108 vocabulary: &N,
109 f: &mut std::fmt::Formatter,
110 _options: &Options,
111 _indent: usize,
112 ) -> std::fmt::Result {
113 string_literal(self.with(vocabulary).as_str(), f)
114 }
115}
116
117impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for Id<T, B> {
118 fn contextual_fmt_with_size(
119 &self,
120 vocabulary: &N,
121 f: &mut std::fmt::Formatter,
122 _options: &Options,
123 _indent: usize,
124 _sizes: &[Size],
125 _index: &mut usize,
126 ) -> std::fmt::Result {
127 string_literal(self.with(vocabulary).as_str(), f)
128 }
129}
130
131impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
132 for Indexed<Object<T, B>>
133{
134 fn contextual_pre_compute_size(
135 &self,
136 vocabulary: &N,
137 options: &Options,
138 sizes: &mut Vec<Size>,
139 ) -> Size {
140 pre_compute_object_size(
141 self.entries().map(|e| {
142 let (k, v) = e.into_key_value();
143 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
144 }),
145 options,
146 sizes,
147 )
148 }
149}
150
151impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
152 for Indexed<Object<T, B>>
153{
154 fn contextual_fmt_with_size(
155 &self,
156 vocabulary: &N,
157 f: &mut std::fmt::Formatter,
158 options: &Options,
159 indent: usize,
160 sizes: &[Size],
161 index: &mut usize,
162 ) -> std::fmt::Result {
163 print_object(
164 self.entries().map(|e| {
165 let (k, v) = e.into_key_value();
166 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
167 }),
168 f,
169 options,
170 indent,
171 sizes,
172 index,
173 )
174 }
175}
176
177impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
178 for object::IndexedEntryValueRef<'a, T, B>
179{
180 fn contextual_pre_compute_size(
181 &self,
182 vocabulary: &N,
183 options: &Options,
184 sizes: &mut Vec<Size>,
185 ) -> Size {
186 match self {
187 object::IndexedEntryValueRef::Index(s) => Size::Width(printed_string_size(s)),
188 object::IndexedEntryValueRef::Object(e) => {
189 e.into_with(vocabulary).pre_compute_size(options, sizes)
190 }
191 }
192 }
193}
194
195impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
196 for object::IndexedEntryValueRef<'a, T, B>
197{
198 fn contextual_fmt_with_size(
199 &self,
200 vocabulary: &N,
201 f: &mut std::fmt::Formatter,
202 options: &Options,
203 indent: usize,
204 sizes: &[Size],
205 index: &mut usize,
206 ) -> std::fmt::Result {
207 match self {
208 object::IndexedEntryValueRef::Index(s) => string_literal(s, f),
209 object::IndexedEntryValueRef::Object(e) => e
210 .into_with(vocabulary)
211 .fmt_with_size(f, options, indent, sizes, index),
212 }
213 }
214}
215
216impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
217 for object::EntryValueRef<'a, T, B>
218{
219 fn contextual_pre_compute_size(
220 &self,
221 vocabulary: &N,
222 options: &Options,
223 sizes: &mut Vec<Size>,
224 ) -> Size {
225 match self {
226 object::EntryValueRef::Value(v) => {
227 v.into_with(vocabulary).pre_compute_size(options, sizes)
228 }
229 object::EntryValueRef::List(l) => {
230 pre_compute_array_size(l.iter().map(|i| i.with(vocabulary)), options, sizes)
231 }
232 object::EntryValueRef::Node(n) => {
233 n.into_with(vocabulary).pre_compute_size(options, sizes)
234 }
235 }
236 }
237}
238
239impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
240 for object::EntryValueRef<'a, T, B>
241{
242 fn contextual_fmt_with_size(
243 &self,
244 vocabulary: &N,
245 f: &mut std::fmt::Formatter,
246 options: &Options,
247 indent: usize,
248 sizes: &[Size],
249 index: &mut usize,
250 ) -> std::fmt::Result {
251 match self {
252 object::EntryValueRef::Value(v) => v
253 .into_with(vocabulary)
254 .fmt_with_size(f, options, indent, sizes, index),
255 object::EntryValueRef::List(l) => print_array(
256 l.iter().map(|i| i.with(vocabulary)),
257 f,
258 options,
259 indent,
260 sizes,
261 index,
262 ),
263 object::EntryValueRef::Node(n) => n
264 .into_with(vocabulary)
265 .fmt_with_size(f, options, indent, sizes, index),
266 }
267 }
268}
269
270impl<'a, T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N>
271 for object::value::EntryRef<'a, T>
272{
273 fn contextual_pre_compute_size(
274 &self,
275 vocabulary: &N,
276 options: &Options,
277 sizes: &mut Vec<Size>,
278 ) -> Size {
279 match self {
280 object::value::EntryRef::Value(v) => v.pre_compute_size(options, sizes),
281 object::value::EntryRef::Type(t) => {
282 t.into_with(vocabulary).pre_compute_size(options, sizes)
283 }
284 object::value::EntryRef::Language(l) => l.pre_compute_size(options, sizes),
285 object::value::EntryRef::Direction(d) => d.pre_compute_size(options, sizes),
286 }
287 }
288}
289
290impl<'a, T, N: IriVocabulary<Iri = T>> PrintWithSizeAndContext<N>
291 for object::value::EntryRef<'a, T>
292{
293 fn contextual_fmt_with_size(
294 &self,
295 vocabulary: &N,
296 f: &mut std::fmt::Formatter,
297 options: &Options,
298 indent: usize,
299 sizes: &[Size],
300 index: &mut usize,
301 ) -> std::fmt::Result {
302 match self {
303 object::value::EntryRef::Value(v) => v.fmt_with_size(f, options, indent, sizes, index),
304 object::value::EntryRef::Type(t) => {
305 t.into_with(vocabulary).fmt_with(f, options, indent)
306 }
307 object::value::EntryRef::Language(l) => l.fmt_with(f, options, indent),
308 object::value::EntryRef::Direction(d) => d.fmt_with(f, options, indent),
309 }
310 }
311}
312
313impl<'a, T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N>
314 for object::value::TypeRef<'a, T>
315{
316 fn contextual_pre_compute_size(
317 &self,
318 vocabulary: &N,
319 _options: &Options,
320 _sizes: &mut Vec<Size>,
321 ) -> Size {
322 match self {
323 object::value::TypeRef::Id(id) => {
324 Size::Width(printed_string_size(vocabulary.iri(id).unwrap().as_str()))
325 }
326 object::value::TypeRef::Json => Size::Width(printed_string_size("@json")),
327 }
328 }
329}
330
331impl<'a, T, N: IriVocabulary<Iri = T>> PrintWithContext<N> for object::value::TypeRef<'a, T> {
332 fn contextual_fmt_with(
333 &self,
334 vocabulary: &N,
335 f: &mut std::fmt::Formatter,
336 _options: &Options,
337 _indent: usize,
338 ) -> std::fmt::Result {
339 match self {
340 object::value::TypeRef::Id(id) => {
341 string_literal(vocabulary.iri(id).unwrap().as_str(), f)
342 }
343 object::value::TypeRef::Json => string_literal("@json", f),
344 }
345 }
346}
347
348impl<'a> PrecomputeSize for object::value::ValueEntryRef<'a> {
349 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
350 match self {
351 Self::Literal(l) => l.pre_compute_size(options, sizes),
352 Self::LangString(s) => Size::Width(printed_string_size(s)),
353 Self::Json(j) => j.pre_compute_size(options, sizes),
354 }
355 }
356}
357
358impl<'a> PrintWithSize for object::value::ValueEntryRef<'a> {
359 fn fmt_with_size(
360 &self,
361 f: &mut std::fmt::Formatter,
362 options: &Options,
363 indent: usize,
364 sizes: &[Size],
365 index: &mut usize,
366 ) -> std::fmt::Result {
367 match self {
368 Self::Literal(l) => l.fmt_with(f, options, indent),
369 Self::LangString(s) => string_literal(s, f),
370 Self::Json(j) => j.fmt_with_size(f, options, indent, sizes, index),
371 }
372 }
373}
374
375impl PrecomputeSize for object::value::Literal {
376 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
377 match self {
378 Self::Null => Size::Width(4),
379 Self::Boolean(b) => b.pre_compute_size(options, sizes),
380 Self::Number(n) => Size::Width(n.as_str().len()),
381 Self::String(s) => Size::Width(printed_string_size(s)),
382 }
383 }
384}
385
386impl Print for object::value::Literal {
387 fn fmt_with(
388 &self,
389 f: &mut std::fmt::Formatter,
390 options: &Options,
391 indent: usize,
392 ) -> std::fmt::Result {
393 match self {
394 Self::Null => write!(f, "null"),
395 Self::Boolean(b) => b.fmt_with(f, options, indent),
396 Self::Number(n) => std::fmt::Display::fmt(n, f),
397 Self::String(s) => string_literal(s, f),
398 }
399 }
400}
401
402impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
403 for object::Node<T, B>
404{
405 fn contextual_pre_compute_size(
406 &self,
407 vocabulary: &N,
408 options: &Options,
409 sizes: &mut Vec<Size>,
410 ) -> Size {
411 pre_compute_object_size(
412 self.entries().map(|e| {
413 let (k, v) = e.into_key_value();
414 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
415 }),
416 options,
417 sizes,
418 )
419 }
420}
421
422impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::Node<T, B> {
423 fn contextual_fmt_with_size(
424 &self,
425 vocabulary: &N,
426 f: &mut std::fmt::Formatter,
427 options: &Options,
428 indent: usize,
429 sizes: &[Size],
430 index: &mut usize,
431 ) -> std::fmt::Result {
432 print_object(
433 self.entries().map(|e| {
434 let (k, v) = e.into_key_value();
435 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
436 }),
437 f,
438 options,
439 indent,
440 sizes,
441 index,
442 )
443 }
444}
445
446impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
447 for Indexed<object::Node<T, B>>
448{
449 fn contextual_pre_compute_size(
450 &self,
451 vocabulary: &N,
452 options: &Options,
453 sizes: &mut Vec<Size>,
454 ) -> Size {
455 pre_compute_object_size(
456 self.entries().map(|e| {
457 let (k, v) = e.into_key_value();
458 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
459 }),
460 options,
461 sizes,
462 )
463 }
464}
465
466impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
467 for Indexed<object::Node<T, B>>
468{
469 fn contextual_fmt_with_size(
470 &self,
471 vocabulary: &N,
472 f: &mut std::fmt::Formatter,
473 options: &Options,
474 indent: usize,
475 sizes: &[Size],
476 index: &mut usize,
477 ) -> std::fmt::Result {
478 print_object(
479 self.entries().map(|e| {
480 let (k, v) = e.into_key_value();
481 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
482 }),
483 f,
484 options,
485 indent,
486 sizes,
487 index,
488 )
489 }
490}
491
492impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
493 for object::node::IndexedEntryValueRef<'a, T, B>
494{
495 fn contextual_pre_compute_size(
496 &self,
497 vocabulary: &N,
498 options: &Options,
499 sizes: &mut Vec<Size>,
500 ) -> Size {
501 match self {
502 object::node::IndexedEntryValueRef::Index(s) => Size::Width(printed_string_size(s)),
503 object::node::IndexedEntryValueRef::Node(e) => {
504 e.into_with(vocabulary).pre_compute_size(options, sizes)
505 }
506 }
507 }
508}
509
510impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
511 for object::node::IndexedEntryValueRef<'a, T, B>
512{
513 fn contextual_fmt_with_size(
514 &self,
515 vocabulary: &N,
516 f: &mut std::fmt::Formatter,
517 options: &Options,
518 indent: usize,
519 sizes: &[Size],
520 index: &mut usize,
521 ) -> std::fmt::Result {
522 match self {
523 object::node::IndexedEntryValueRef::Index(s) => string_literal(s, f),
524 object::node::IndexedEntryValueRef::Node(e) => e
525 .into_with(vocabulary)
526 .fmt_with_size(f, options, indent, sizes, index),
527 }
528 }
529}
530
531impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
532 for object::node::EntryValueRef<'a, T, B>
533{
534 fn contextual_pre_compute_size(
535 &self,
536 vocabulary: &N,
537 options: &Options,
538 sizes: &mut Vec<Size>,
539 ) -> Size {
540 match *self {
541 object::node::EntryValueRef::Id(v) => {
542 v.contextual_pre_compute_size(vocabulary, options, sizes)
543 }
544 object::node::EntryValueRef::Type(v) => {
545 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
546 }
547 object::node::EntryValueRef::Graph(v) => {
548 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
549 }
551 object::node::EntryValueRef::Included(v) => {
552 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
553 }
555 object::node::EntryValueRef::Reverse(v) => {
556 v.contextual_pre_compute_size(vocabulary, options, sizes)
557 }
558 object::node::EntryValueRef::Property(v) => {
559 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
560 }
561 }
562 }
563}
564
565impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
566 for object::node::EntryValueRef<'a, T, B>
567{
568 fn contextual_fmt_with_size(
569 &self,
570 vocabulary: &N,
571 f: &mut std::fmt::Formatter,
572 options: &Options,
573 indent: usize,
574 sizes: &[Size],
575 index: &mut usize,
576 ) -> std::fmt::Result {
577 match self {
578 object::node::EntryValueRef::Id(v) => v.with(vocabulary).fmt_with(f, options, indent),
579 object::node::EntryValueRef::Type(v) => print_array(
580 v.iter().map(|i| i.with(vocabulary)),
581 f,
582 options,
583 indent,
584 sizes,
585 index,
586 ),
587 object::node::EntryValueRef::Graph(v) => {
588 print_array(
590 v.iter().map(|i| i.with(vocabulary)),
591 f,
592 options,
593 indent,
594 sizes,
595 index,
596 )
597 }
598 object::node::EntryValueRef::Included(v) => {
599 print_array(
601 v.iter().map(|i| i.with(vocabulary)),
602 f,
603 options,
604 indent,
605 sizes,
606 index,
607 )
608 }
609 object::node::EntryValueRef::Reverse(v) => {
610 v.contextual_fmt_with_size(vocabulary, f, options, indent, sizes, index)
611 }
612 object::node::EntryValueRef::Property(v) => print_array(
613 v.iter().map(|i| i.with(vocabulary)),
614 f,
615 options,
616 indent,
617 sizes,
618 index,
619 ),
620 }
621 }
622}
623
624impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
625 for object::node::ReverseProperties<T, B>
626{
627 fn contextual_pre_compute_size(
628 &self,
629 vocabulary: &N,
630 options: &Options,
631 sizes: &mut Vec<Size>,
632 ) -> Size {
633 pre_compute_object_size(
634 self.iter()
635 .map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
636 options,
637 sizes,
638 )
639 }
640}
641
642impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
643 for object::node::ReverseProperties<T, B>
644{
645 fn contextual_fmt_with_size(
646 &self,
647 vocabulary: &N,
648 f: &mut std::fmt::Formatter,
649 options: &Options,
650 indent: usize,
651 sizes: &[Size],
652 index: &mut usize,
653 ) -> std::fmt::Result {
654 print_object(
655 self.iter()
656 .map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
657 f,
658 options,
659 indent,
660 sizes,
661 index,
662 )
663 }
664}