json_ld_core_next/
print.rs

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				// v.contextual_pre_compute_size(vocabulary, options, sizes)
544			}
545			object::node::EntryValueRef::Included(v) => {
546				pre_compute_array_size(v.iter().map(|i| i.with(vocabulary)), options, sizes)
547				// v.contextual_pre_compute_size(vocabulary, options, sizes)
548			}
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				// v.contextual_fmt_with_size(vocabulary, f, options, indent, sizes, index)
583				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				// v.contextual_fmt_with_size(vocabulary, f, options, indent, sizes, index)
594				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}