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<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
178 for object::IndexedEntryValueRef<'_, 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<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
196 for object::IndexedEntryValueRef<'_, 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<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
217 for object::EntryValueRef<'_, 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<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
240 for object::EntryValueRef<'_, 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<T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N> for object::value::EntryRef<'_, T> {
271 fn contextual_pre_compute_size(
272 &self,
273 vocabulary: &N,
274 options: &Options,
275 sizes: &mut Vec<Size>,
276 ) -> Size {
277 match self {
278 object::value::EntryRef::Value(v) => v.pre_compute_size(options, sizes),
279 object::value::EntryRef::Type(t) => {
280 t.into_with(vocabulary).pre_compute_size(options, sizes)
281 }
282 object::value::EntryRef::Language(l) => l.pre_compute_size(options, sizes),
283 object::value::EntryRef::Direction(d) => d.pre_compute_size(options, sizes),
284 }
285 }
286}
287
288impl<T, N: IriVocabulary<Iri = T>> PrintWithSizeAndContext<N> for object::value::EntryRef<'_, T> {
289 fn contextual_fmt_with_size(
290 &self,
291 vocabulary: &N,
292 f: &mut std::fmt::Formatter,
293 options: &Options,
294 indent: usize,
295 sizes: &[Size],
296 index: &mut usize,
297 ) -> std::fmt::Result {
298 match self {
299 object::value::EntryRef::Value(v) => v.fmt_with_size(f, options, indent, sizes, index),
300 object::value::EntryRef::Type(t) => {
301 t.into_with(vocabulary).fmt_with(f, options, indent)
302 }
303 object::value::EntryRef::Language(l) => l.fmt_with(f, options, indent),
304 object::value::EntryRef::Direction(d) => d.fmt_with(f, options, indent),
305 }
306 }
307}
308
309impl<T, N: IriVocabulary<Iri = T>> PrecomputeSizeWithContext<N> for object::value::TypeRef<'_, T> {
310 fn contextual_pre_compute_size(
311 &self,
312 vocabulary: &N,
313 _options: &Options,
314 _sizes: &mut Vec<Size>,
315 ) -> Size {
316 match self {
317 object::value::TypeRef::Id(id) => {
318 Size::Width(printed_string_size(vocabulary.iri(id).unwrap().as_str()))
319 }
320 object::value::TypeRef::Json => Size::Width(printed_string_size("@json")),
321 }
322 }
323}
324
325impl<T, N: IriVocabulary<Iri = T>> PrintWithContext<N> for object::value::TypeRef<'_, T> {
326 fn contextual_fmt_with(
327 &self,
328 vocabulary: &N,
329 f: &mut std::fmt::Formatter,
330 _options: &Options,
331 _indent: usize,
332 ) -> std::fmt::Result {
333 match self {
334 object::value::TypeRef::Id(id) => {
335 string_literal(vocabulary.iri(id).unwrap().as_str(), f)
336 }
337 object::value::TypeRef::Json => string_literal("@json", f),
338 }
339 }
340}
341
342impl PrecomputeSize for object::value::ValueEntryRef<'_> {
343 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
344 match self {
345 Self::Literal(l) => l.pre_compute_size(options, sizes),
346 Self::LangString(s) => Size::Width(printed_string_size(s)),
347 Self::Json(j) => j.pre_compute_size(options, sizes),
348 }
349 }
350}
351
352impl PrintWithSize for object::value::ValueEntryRef<'_> {
353 fn fmt_with_size(
354 &self,
355 f: &mut std::fmt::Formatter,
356 options: &Options,
357 indent: usize,
358 sizes: &[Size],
359 index: &mut usize,
360 ) -> std::fmt::Result {
361 match self {
362 Self::Literal(l) => l.fmt_with(f, options, indent),
363 Self::LangString(s) => string_literal(s, f),
364 Self::Json(j) => j.fmt_with_size(f, options, indent, sizes, index),
365 }
366 }
367}
368
369impl PrecomputeSize for object::value::Literal {
370 fn pre_compute_size(&self, options: &Options, sizes: &mut Vec<Size>) -> Size {
371 match self {
372 Self::Null => Size::Width(4),
373 Self::Boolean(b) => b.pre_compute_size(options, sizes),
374 Self::Number(n) => Size::Width(n.as_str().len()),
375 Self::String(s) => Size::Width(printed_string_size(s)),
376 }
377 }
378}
379
380impl Print for object::value::Literal {
381 fn fmt_with(
382 &self,
383 f: &mut std::fmt::Formatter,
384 options: &Options,
385 indent: usize,
386 ) -> std::fmt::Result {
387 match self {
388 Self::Null => write!(f, "null"),
389 Self::Boolean(b) => b.fmt_with(f, options, indent),
390 Self::Number(n) => std::fmt::Display::fmt(n, f),
391 Self::String(s) => string_literal(s, f),
392 }
393 }
394}
395
396impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
397 for object::Node<T, B>
398{
399 fn contextual_pre_compute_size(
400 &self,
401 vocabulary: &N,
402 options: &Options,
403 sizes: &mut Vec<Size>,
404 ) -> Size {
405 pre_compute_object_size(
406 self.entries().map(|e| {
407 let (k, v) = e.into_key_value();
408 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
409 }),
410 options,
411 sizes,
412 )
413 }
414}
415
416impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N> for object::Node<T, B> {
417 fn contextual_fmt_with_size(
418 &self,
419 vocabulary: &N,
420 f: &mut std::fmt::Formatter,
421 options: &Options,
422 indent: usize,
423 sizes: &[Size],
424 index: &mut usize,
425 ) -> std::fmt::Result {
426 print_object(
427 self.entries().map(|e| {
428 let (k, v) = e.into_key_value();
429 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
430 }),
431 f,
432 options,
433 indent,
434 sizes,
435 index,
436 )
437 }
438}
439
440impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
441 for Indexed<object::Node<T, B>>
442{
443 fn contextual_pre_compute_size(
444 &self,
445 vocabulary: &N,
446 options: &Options,
447 sizes: &mut Vec<Size>,
448 ) -> Size {
449 pre_compute_object_size(
450 self.entries().map(|e| {
451 let (k, v) = e.into_key_value();
452 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
453 }),
454 options,
455 sizes,
456 )
457 }
458}
459
460impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
461 for Indexed<object::Node<T, B>>
462{
463 fn contextual_fmt_with_size(
464 &self,
465 vocabulary: &N,
466 f: &mut std::fmt::Formatter,
467 options: &Options,
468 indent: usize,
469 sizes: &[Size],
470 index: &mut usize,
471 ) -> std::fmt::Result {
472 print_object(
473 self.entries().map(|e| {
474 let (k, v) = e.into_key_value();
475 (k.into_with(vocabulary).into_str(), v.into_with(vocabulary))
476 }),
477 f,
478 options,
479 indent,
480 sizes,
481 index,
482 )
483 }
484}
485
486impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
487 for object::node::IndexedEntryValueRef<'_, T, B>
488{
489 fn contextual_pre_compute_size(
490 &self,
491 vocabulary: &N,
492 options: &Options,
493 sizes: &mut Vec<Size>,
494 ) -> Size {
495 match self {
496 object::node::IndexedEntryValueRef::Index(s) => Size::Width(printed_string_size(s)),
497 object::node::IndexedEntryValueRef::Node(e) => {
498 e.into_with(vocabulary).pre_compute_size(options, sizes)
499 }
500 }
501 }
502}
503
504impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
505 for object::node::IndexedEntryValueRef<'_, T, B>
506{
507 fn contextual_fmt_with_size(
508 &self,
509 vocabulary: &N,
510 f: &mut std::fmt::Formatter,
511 options: &Options,
512 indent: usize,
513 sizes: &[Size],
514 index: &mut usize,
515 ) -> std::fmt::Result {
516 match self {
517 object::node::IndexedEntryValueRef::Index(s) => string_literal(s, f),
518 object::node::IndexedEntryValueRef::Node(e) => e
519 .into_with(vocabulary)
520 .fmt_with_size(f, options, indent, sizes, index),
521 }
522 }
523}
524
525impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
526 for object::node::EntryValueRef<'_, T, B>
527{
528 fn contextual_pre_compute_size(
529 &self,
530 vocabulary: &N,
531 options: &Options,
532 sizes: &mut Vec<Size>,
533 ) -> Size {
534 match *self {
535 object::node::EntryValueRef::Id(v) => {
536 v.contextual_pre_compute_size(vocabulary, options, sizes)
537 }
538 object::node::EntryValueRef::Type(v) => {
539 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
540 }
541 object::node::EntryValueRef::Graph(v) => {
542 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
543 }
545 object::node::EntryValueRef::Included(v) => {
546 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
547 }
549 object::node::EntryValueRef::Reverse(v) => {
550 v.contextual_pre_compute_size(vocabulary, options, sizes)
551 }
552 object::node::EntryValueRef::Property(v) => {
553 pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
554 }
555 }
556 }
557}
558
559impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
560 for object::node::EntryValueRef<'_, T, B>
561{
562 fn contextual_fmt_with_size(
563 &self,
564 vocabulary: &N,
565 f: &mut std::fmt::Formatter,
566 options: &Options,
567 indent: usize,
568 sizes: &[Size],
569 index: &mut usize,
570 ) -> std::fmt::Result {
571 match self {
572 object::node::EntryValueRef::Id(v) => v.with(vocabulary).fmt_with(f, options, indent),
573 object::node::EntryValueRef::Type(v) => print_array(
574 v.iter().map(|i| i.with(vocabulary)),
575 f,
576 options,
577 indent,
578 sizes,
579 index,
580 ),
581 object::node::EntryValueRef::Graph(v) => {
582 print_array(
584 v.iter().map(|i| i.with(vocabulary)),
585 f,
586 options,
587 indent,
588 sizes,
589 index,
590 )
591 }
592 object::node::EntryValueRef::Included(v) => {
593 print_array(
595 v.iter().map(|i| i.with(vocabulary)),
596 f,
597 options,
598 indent,
599 sizes,
600 index,
601 )
602 }
603 object::node::EntryValueRef::Reverse(v) => {
604 v.contextual_fmt_with_size(vocabulary, f, options, indent, sizes, index)
605 }
606 object::node::EntryValueRef::Property(v) => print_array(
607 v.iter().map(|i| i.with(vocabulary)),
608 f,
609 options,
610 indent,
611 sizes,
612 index,
613 ),
614 }
615 }
616}
617
618impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrecomputeSizeWithContext<N>
619 for object::node::ReverseProperties<T, B>
620{
621 fn contextual_pre_compute_size(
622 &self,
623 vocabulary: &N,
624 options: &Options,
625 sizes: &mut Vec<Size>,
626 ) -> Size {
627 pre_compute_object_size(
628 self.iter()
629 .map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
630 options,
631 sizes,
632 )
633 }
634}
635
636impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> PrintWithSizeAndContext<N>
637 for object::node::ReverseProperties<T, B>
638{
639 fn contextual_fmt_with_size(
640 &self,
641 vocabulary: &N,
642 f: &mut std::fmt::Formatter,
643 options: &Options,
644 indent: usize,
645 sizes: &[Size],
646 index: &mut usize,
647 ) -> std::fmt::Result {
648 print_object(
649 self.iter()
650 .map(|(k, v)| (k.into_with(vocabulary).as_str(), v.into_with(vocabulary))),
651 f,
652 options,
653 indent,
654 sizes,
655 index,
656 )
657 }
658}