json_ld_core/object/
mod.rs

1//! Nodes, lists and values.
2use crate::{Id, Indexed, LenientLangTag, Relabel};
3use contextual::{IntoRefWithContext, WithContext};
4use educe::Educe;
5use indexmap::IndexSet;
6use iref::IriBuf;
7use json_ld_syntax::{IntoJsonWithContext, Keyword};
8use json_syntax::Number;
9use rdf_types::{BlankIdBuf, Generator, Subject, Vocabulary, VocabularyMut};
10use smallvec::SmallVec;
11use std::hash::Hash;
12
13pub mod list;
14mod mapped_eq;
15pub mod node;
16mod typ;
17pub mod value;
18
19pub use list::List;
20pub use mapped_eq::MappedEq;
21pub use node::{Graph, IndexedNode, Node, Nodes};
22pub use typ::{Type, TypeRef};
23pub use value::{Literal, Value};
24
25/// Abstract object.
26pub trait Any<T, B> {
27	fn as_ref(&self) -> Ref<T, B>;
28
29	#[inline]
30	fn id(&self) -> Option<&Id<T, B>> {
31		match self.as_ref() {
32			Ref::Node(n) => n.id.as_ref(),
33			_ => None,
34		}
35	}
36
37	#[inline]
38	fn language<'a>(&'a self) -> Option<&'a LenientLangTag>
39	where
40		T: 'a,
41		B: 'a,
42	{
43		match self.as_ref() {
44			Ref::Value(value) => value.language(),
45			_ => None,
46		}
47	}
48
49	#[inline]
50	fn is_value(&self) -> bool {
51		matches!(self.as_ref(), Ref::Value(_))
52	}
53
54	#[inline]
55	fn is_node(&self) -> bool {
56		matches!(self.as_ref(), Ref::Node(_))
57	}
58
59	#[inline]
60	fn is_graph(&self) -> bool {
61		match self.as_ref() {
62			Ref::Node(n) => n.is_graph(),
63			_ => false,
64		}
65	}
66
67	#[inline]
68	fn is_list(&self) -> bool {
69		matches!(self.as_ref(), Ref::List(_))
70	}
71}
72
73/// Object reference.
74pub enum Ref<'a, T, B> {
75	/// Value object.
76	Value(&'a Value<T>),
77
78	/// Node object.
79	Node(&'a Node<T, B>),
80
81	/// List object.
82	List(&'a List<T, B>),
83}
84
85/// Indexed object.
86pub type IndexedObject<T, B = ()> = Indexed<Object<T, B>>;
87
88/// Object.
89///
90/// JSON-LD connects together multiple kinds of data objects.
91/// Objects may be nodes, values or lists of objects.
92///
93/// You can get an `Object` by expanding a JSON-LD document using the
94/// expansion algorithm or by converting an already expanded JSON document
95/// using [`TryFromJson`].
96#[allow(clippy::derived_hash_with_manual_eq)]
97#[derive(Educe, Debug, Clone, Hash)]
98#[educe(
99	PartialEq(bound = "T: Eq + Hash, B: Eq + Hash"),
100	Eq(bound = "T: Eq + Hash, B: Eq + Hash")
101)]
102pub enum Object<T = IriBuf, B = BlankIdBuf> {
103	/// Value object.
104	Value(Value<T>),
105
106	/// Node object.
107	Node(Box<Node<T, B>>),
108
109	/// List object.
110	List(List<T, B>),
111}
112
113impl<T, B> Object<T, B> {
114	/// Creates a `null` value object.
115	#[inline(always)]
116	pub fn null() -> Self {
117		Self::Value(Value::null())
118	}
119
120	/// Creates a new node object from a node.
121	#[inline(always)]
122	pub fn node(n: Node<T, B>) -> Self {
123		Self::Node(Box::new(n))
124	}
125
126	/// Identifier of the object, if it is a node object.
127	#[inline(always)]
128	pub fn id(&self) -> Option<&Id<T, B>> {
129		match self {
130			Object::Node(n) => n.id.as_ref(),
131			_ => None,
132		}
133	}
134
135	/// Assigns an identifier to every node included in this object using the given `generator`.
136	pub fn identify_all_with<V: Vocabulary<Iri = T, BlankId = B>, G: Generator<V>>(
137		&mut self,
138		vocabulary: &mut V,
139		generator: &mut G,
140	) where
141		T: Eq + Hash,
142		B: Eq + Hash,
143	{
144		match self {
145			Object::Node(n) => n.identify_all_with(vocabulary, generator),
146			Object::List(l) => {
147				for object in l {
148					object.identify_all_with(vocabulary, generator)
149				}
150			}
151			_ => (),
152		}
153	}
154
155	/// Use the given `generator` to assign an identifier to all nodes that
156	/// don't have one.
157	pub fn identify_all<G: Generator>(&mut self, generator: &mut G)
158	where
159		T: Eq + Hash,
160		B: Eq + Hash,
161		(): Vocabulary<Iri = T, BlankId = B>,
162	{
163		self.identify_all_with(&mut (), generator)
164	}
165
166	/// Puts this object literals into canonical form using the given
167	/// `buffer`.
168	///
169	/// The buffer is used to compute the canonical form of numbers.
170	pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
171		match self {
172			Self::List(l) => l.canonicalize_with(buffer),
173			Self::Node(n) => n.canonicalize_with(buffer),
174			Self::Value(v) => v.canonicalize_with(buffer),
175		}
176	}
177
178	/// Puts this object literals into canonical form.
179	pub fn canonicalize(&mut self) {
180		let mut buffer = ryu_js::Buffer::new();
181		self.canonicalize_with(&mut buffer)
182	}
183
184	/// Returns an iterator over the types of the object.
185	pub fn types(&self) -> Types<T, B> {
186		match self {
187			Self::Value(value) => Types::Value(value.typ()),
188			Self::Node(node) => Types::Node(node.types().iter()),
189			Self::List(_) => Types::List,
190		}
191	}
192
193	/// Identifier of the object as an IRI.
194	///
195	/// If the object is a node identified by an IRI, returns this IRI.
196	/// Returns `None` otherwise.
197	#[inline(always)]
198	pub fn as_iri(&self) -> Option<&T> {
199		match self {
200			Object::Node(node) => node.as_iri(),
201			_ => None,
202		}
203	}
204
205	/// Tests if the object is a value.
206	#[inline(always)]
207	pub fn is_value(&self) -> bool {
208		matches!(self, Object::Value(_))
209	}
210
211	/// Returns this object as a value, if it is one.
212	#[inline(always)]
213	pub fn as_value(&self) -> Option<&Value<T>> {
214		match self {
215			Self::Value(v) => Some(v),
216			_ => None,
217		}
218	}
219
220	/// Returns this object as a mutable value, if it is one.
221	#[inline(always)]
222	pub fn as_value_mut(&mut self) -> Option<&mut Value<T>> {
223		match self {
224			Self::Value(v) => Some(v),
225			_ => None,
226		}
227	}
228
229	/// Converts this object as a value, if it is one.
230	#[inline(always)]
231	pub fn into_value(self) -> Option<Value<T>> {
232		match self {
233			Self::Value(v) => Some(v),
234			_ => None,
235		}
236	}
237
238	/// Tests if the object is a node.
239	#[inline(always)]
240	pub fn is_node(&self) -> bool {
241		matches!(self, Object::Node(_))
242	}
243
244	/// Returns this object as a node, if it is one.
245	#[inline(always)]
246	pub fn as_node(&self) -> Option<&Node<T, B>> {
247		match self {
248			Self::Node(n) => Some(n),
249			_ => None,
250		}
251	}
252
253	/// Returns this object as a mutable node, if it is one.
254	#[inline(always)]
255	pub fn as_node_mut(&mut self) -> Option<&mut Node<T, B>> {
256		match self {
257			Self::Node(n) => Some(n),
258			_ => None,
259		}
260	}
261
262	/// Converts this object into a node, if it is one.
263	#[inline(always)]
264	pub fn into_node(self) -> Option<Node<T, B>> {
265		match self {
266			Self::Node(n) => Some(*n),
267			_ => None,
268		}
269	}
270
271	/// Tests if the object is a graph object (a node with a `@graph` field).
272	#[inline(always)]
273	pub fn is_graph(&self) -> bool {
274		match self {
275			Object::Node(n) => n.is_graph(),
276			_ => false,
277		}
278	}
279
280	/// Tests if the object is a list.
281	#[inline(always)]
282	pub fn is_list(&self) -> bool {
283		matches!(self, Object::List(_))
284	}
285
286	/// Returns this object as a list, if it is one.
287	#[inline(always)]
288	pub fn as_list(&self) -> Option<&List<T, B>> {
289		match self {
290			Self::List(l) => Some(l),
291			_ => None,
292		}
293	}
294
295	/// Returns this object as a mutable list, if it is one.
296	#[inline(always)]
297	pub fn as_list_mut(&mut self) -> Option<&mut List<T, B>> {
298		match self {
299			Self::List(l) => Some(l),
300			_ => None,
301		}
302	}
303
304	/// Converts this object into a list, if it is one.
305	#[inline(always)]
306	pub fn into_list(self) -> Option<List<T, B>> {
307		match self {
308			Self::List(l) => Some(l),
309			_ => None,
310		}
311	}
312
313	/// Get the object as a string.
314	///
315	/// If the object is a value that is a string, returns this string.
316	/// If the object is a node that is identified, returns the identifier as a string.
317	/// Returns `None` otherwise.
318	#[inline(always)]
319	pub fn as_str(&self) -> Option<&str>
320	where
321		T: AsRef<str>,
322		B: AsRef<str>,
323	{
324		match self {
325			Object::Value(value) => value.as_str(),
326			Object::Node(node) => node.as_str(),
327			_ => None,
328		}
329	}
330
331	/// Get the value as a boolean, if it is.
332	#[inline(always)]
333	pub fn as_bool(&self) -> Option<bool> {
334		match self {
335			Object::Value(value) => value.as_bool(),
336			_ => None,
337		}
338	}
339
340	/// Get the value as a number, if it is.
341	#[inline(always)]
342	pub fn as_number(&self) -> Option<&Number> {
343		match self {
344			Object::Value(value) => value.as_number(),
345			_ => None,
346		}
347	}
348
349	/// If the object is a language-tagged value,
350	/// Return its associated language.
351	#[inline(always)]
352	pub fn language(&self) -> Option<&LenientLangTag> {
353		match self {
354			Object::Value(value) => value.language(),
355			_ => None,
356		}
357	}
358
359	/// Returns an iterator over all fragments of this object, including the
360	/// object itself.
361	///
362	/// Fragments include:
363	///   - objects
364	///   - key-value pairs,
365	///   - keys
366	///   - values
367	pub fn traverse(&self) -> Traverse<T, B> {
368		Traverse::new(Some(FragmentRef::Object(self)))
369	}
370
371	fn sub_fragments(&self) -> ObjectSubFragments<T, B> {
372		match self {
373			Self::Value(v) => ObjectSubFragments::Value(v.entries()),
374			Self::List(l) => ObjectSubFragments::List(Some(l.entry())),
375			Self::Node(n) => ObjectSubFragments::Node(n.entries()),
376		}
377	}
378
379	/// Equivalence operator.
380	///
381	/// Equivalence is different from equality for anonymous objects:
382	/// List objects and anonymous node objects have an implicit unlabeled blank nodes and thus never equivalent.
383	pub fn equivalent(&self, other: &Self) -> bool
384	where
385		T: Eq + Hash,
386		B: Eq + Hash,
387	{
388		match (self, other) {
389			(Self::Value(a), Self::Value(b)) => a == b,
390			(Self::Node(a), Self::Node(b)) => a.equivalent(b),
391			_ => false,
392		}
393	}
394
395	/// Returns an iterator over the entries of JSON representation of the
396	/// object.
397	pub fn entries(&self) -> Entries<T, B> {
398		match self {
399			Self::Value(value) => Entries::Value(value.entries()),
400			Self::List(list) => Entries::List(Some(list.entry())),
401			Self::Node(node) => Entries::Node(node.entries()),
402		}
403	}
404
405	/// Map the identifiers present in this object (recursively).
406	pub fn map_ids<U, C>(
407		self,
408		mut map_iri: impl FnMut(T) -> U,
409		mut map_id: impl FnMut(Id<T, B>) -> Id<U, C>,
410	) -> Object<U, C>
411	where
412		U: Eq + Hash,
413		C: Eq + Hash,
414	{
415		self.map_ids_with(&mut map_iri, &mut map_id)
416	}
417
418	fn map_ids_with<U, C>(
419		self,
420		map_iri: &mut impl FnMut(T) -> U,
421		map_id: &mut impl FnMut(Id<T, B>) -> Id<U, C>,
422	) -> Object<U, C>
423	where
424		U: Eq + Hash,
425		C: Eq + Hash,
426	{
427		match self {
428			Self::Value(value) => Object::Value(value.map_ids(map_iri)),
429			Self::List(list) => Object::List(list.map_ids_with(map_iri, map_id)),
430			Self::Node(node) => Object::Node(Box::new((*node).map_ids_with(map_iri, map_id))),
431		}
432	}
433}
434
435impl<T, B> Relabel<T, B> for Object<T, B> {
436	fn relabel_with<N: Vocabulary<Iri = T, BlankId = B>, G: Generator<N>>(
437		&mut self,
438		vocabulary: &mut N,
439		generator: &mut G,
440		relabeling: &mut hashbrown::HashMap<B, Subject<T, B>>,
441	) where
442		T: Clone + Eq + Hash,
443		B: Clone + Eq + Hash,
444	{
445		match self {
446			Self::Node(n) => n.relabel_with(vocabulary, generator, relabeling),
447			Self::List(l) => l.relabel_with(vocabulary, generator, relabeling),
448			Self::Value(_) => (),
449		}
450	}
451}
452
453impl<T: Eq + Hash, B: Eq + Hash> Indexed<Object<T, B>> {
454	pub fn equivalent(&self, other: &Self) -> bool {
455		self.index() == other.index() && self.inner().equivalent(other.inner())
456	}
457}
458
459impl<T, B> Indexed<Object<T, B>> {
460	/// Converts this indexed object into an indexed node, if it is one.
461	#[inline(always)]
462	pub fn into_indexed_node(self) -> Option<Indexed<Node<T, B>>> {
463		let (object, index) = self.into_parts();
464		object.into_node().map(|node| Indexed::new(node, index))
465	}
466
467	/// Converts this indexed object into an indexed node, if it is one.
468	#[inline(always)]
469	pub fn into_indexed_value(self) -> Option<Indexed<Value<T>>> {
470		let (object, index) = self.into_parts();
471		object.into_value().map(|value| Indexed::new(value, index))
472	}
473
474	/// Converts this indexed object into an indexed list, if it is one.
475	#[inline(always)]
476	pub fn into_indexed_list(self) -> Option<Indexed<List<T, B>>> {
477		let (object, index) = self.into_parts();
478		object.into_list().map(|list| Indexed::new(list, index))
479	}
480
481	/// Try to convert this object into an unnamed graph.
482	pub fn into_unnamed_graph(self) -> Result<Graph<T, B>, Self> {
483		let (obj, index) = self.into_parts();
484		match obj {
485			Object::Node(n) => match n.into_unnamed_graph() {
486				Ok(g) => Ok(g),
487				Err(n) => Err(Indexed::new(Object::node(n), index)),
488			},
489			obj => Err(Indexed::new(obj, index)),
490		}
491	}
492
493	pub fn entries(&self) -> IndexedEntries<T, B> {
494		IndexedEntries {
495			index: self.index(),
496			inner: self.inner().entries(),
497		}
498	}
499}
500
501#[derive(Educe)]
502#[educe(Clone)]
503pub enum Entries<'a, T, B> {
504	Value(value::Entries<'a, T>),
505	List(Option<&'a [IndexedObject<T, B>]>),
506	Node(node::Entries<'a, T, B>),
507}
508
509impl<'a, T, B> Iterator for Entries<'a, T, B> {
510	type Item = EntryRef<'a, T, B>;
511
512	fn size_hint(&self) -> (usize, Option<usize>) {
513		let len = match self {
514			Self::Value(v) => v.len(),
515			Self::List(l) => usize::from(l.is_some()),
516			Self::Node(n) => n.len(),
517		};
518
519		(len, Some(len))
520	}
521
522	fn next(&mut self) -> Option<Self::Item> {
523		match self {
524			Self::Value(v) => v.next().map(EntryRef::Value),
525			Self::List(l) => l.take().map(EntryRef::List),
526			Self::Node(n) => n.next().map(EntryRef::Node),
527		}
528	}
529}
530
531impl<'a, T, B> ExactSizeIterator for Entries<'a, T, B> {}
532
533#[derive(Educe)]
534#[educe(Clone)]
535pub struct IndexedEntries<'a, T, B> {
536	index: Option<&'a str>,
537	inner: Entries<'a, T, B>,
538}
539
540impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
541	type Item = IndexedEntryRef<'a, T, B>;
542
543	fn size_hint(&self) -> (usize, Option<usize>) {
544		let len = self.inner.len() + usize::from(self.index.is_some());
545		(len, Some(len))
546	}
547
548	fn next(&mut self) -> Option<Self::Item> {
549		self.index
550			.take()
551			.map(IndexedEntryRef::Index)
552			.or_else(|| self.inner.next().map(IndexedEntryRef::Object))
553	}
554}
555
556impl<'a, T, B> ExactSizeIterator for IndexedEntries<'a, T, B> {}
557
558#[derive(Educe, PartialEq, Eq)]
559#[educe(Clone, Copy)]
560pub enum EntryKeyRef<'a, T, B> {
561	Value(value::EntryKey),
562	List,
563	Node(node::EntryKeyRef<'a, T, B>),
564}
565
566impl<'a, T, B> EntryKeyRef<'a, T, B> {
567	pub fn into_keyword(self) -> Option<Keyword> {
568		match self {
569			Self::Value(e) => Some(e.into_keyword()),
570			Self::List => Some(Keyword::List),
571			Self::Node(e) => e.into_keyword(),
572		}
573	}
574
575	pub fn as_keyword(&self) -> Option<Keyword> {
576		self.into_keyword()
577	}
578
579	pub fn into_str(self) -> &'a str
580	where
581		T: AsRef<str>,
582		B: AsRef<str>,
583	{
584		match self {
585			Self::Value(e) => e.into_str(),
586			Self::List => "@list",
587			Self::Node(e) => e.into_str(),
588		}
589	}
590
591	pub fn as_str(self) -> &'a str
592	where
593		T: AsRef<str>,
594		B: AsRef<str>,
595	{
596		self.into_str()
597	}
598}
599
600impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N>
601	for EntryKeyRef<'a, T, B>
602{
603	fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
604		match self {
605			EntryKeyRef::Value(e) => e.into_str(),
606			EntryKeyRef::List => "@list",
607			EntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
608		}
609	}
610}
611
612#[derive(Educe)]
613#[educe(Clone, Copy)]
614pub enum EntryValueRef<'a, T, B> {
615	Value(value::EntryRef<'a, T>),
616	List(&'a [IndexedObject<T, B>]),
617	Node(node::EntryValueRef<'a, T, B>),
618}
619
620#[derive(Educe)]
621#[educe(Clone, Copy)]
622pub enum EntryRef<'a, T, B> {
623	Value(value::EntryRef<'a, T>),
624	List(&'a [IndexedObject<T, B>]),
625	Node(node::EntryRef<'a, T, B>),
626}
627
628impl<'a, T, B> EntryRef<'a, T, B> {
629	pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
630		match self {
631			Self::Value(e) => EntryKeyRef::Value(e.key()),
632			Self::List(_) => EntryKeyRef::List,
633			Self::Node(e) => EntryKeyRef::Node(e.key()),
634		}
635	}
636
637	pub fn key(&self) -> EntryKeyRef<'a, T, B> {
638		self.into_key()
639	}
640
641	pub fn into_value(self) -> EntryValueRef<'a, T, B> {
642		match self {
643			Self::Value(v) => EntryValueRef::Value(v),
644			Self::List(v) => EntryValueRef::List(v),
645			Self::Node(e) => EntryValueRef::Node(e.value()),
646		}
647	}
648
649	pub fn value(&self) -> EntryValueRef<'a, T, B> {
650		self.into_value()
651	}
652
653	pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
654		match self {
655			Self::Value(e) => (EntryKeyRef::Value(e.key()), EntryValueRef::Value(e)),
656			Self::List(e) => (EntryKeyRef::List, EntryValueRef::List(e)),
657			Self::Node(e) => {
658				let (k, v) = e.into_key_value();
659				(EntryKeyRef::Node(k), EntryValueRef::Node(v))
660			}
661		}
662	}
663
664	pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
665		self.into_key_value()
666	}
667}
668
669#[derive(Educe, PartialEq, Eq)]
670#[educe(Clone, Copy)]
671pub enum IndexedEntryKeyRef<'a, T, B> {
672	Index,
673	Object(EntryKeyRef<'a, T, B>),
674}
675
676impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
677	pub fn into_keyword(self) -> Option<Keyword> {
678		match self {
679			Self::Index => Some(Keyword::Index),
680			Self::Object(e) => e.into_keyword(),
681		}
682	}
683
684	pub fn as_keyword(&self) -> Option<Keyword> {
685		self.into_keyword()
686	}
687
688	pub fn into_str(self) -> &'a str
689	where
690		T: AsRef<str>,
691		B: AsRef<str>,
692	{
693		match self {
694			Self::Index => "@index",
695			Self::Object(e) => e.into_str(),
696		}
697	}
698
699	pub fn as_str(&self) -> &'a str
700	where
701		T: AsRef<str>,
702		B: AsRef<str>,
703	{
704		self.into_str()
705	}
706}
707
708impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N>
709	for IndexedEntryKeyRef<'a, T, B>
710{
711	fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
712		match self {
713			IndexedEntryKeyRef::Index => "@value",
714			IndexedEntryKeyRef::Object(e) => e.into_with(vocabulary).into_str(),
715		}
716	}
717}
718
719#[derive(Educe)]
720#[educe(Clone, Copy)]
721pub enum IndexedEntryValueRef<'a, T, B> {
722	Index(&'a str),
723	Object(EntryValueRef<'a, T, B>),
724}
725
726#[derive(Educe)]
727#[educe(Clone, Copy)]
728pub enum IndexedEntryRef<'a, T, B> {
729	Index(&'a str),
730	Object(EntryRef<'a, T, B>),
731}
732
733impl<'a, T, B> IndexedEntryRef<'a, T, B> {
734	pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
735		match self {
736			Self::Index(_) => IndexedEntryKeyRef::Index,
737			Self::Object(e) => IndexedEntryKeyRef::Object(e.key()),
738		}
739	}
740
741	pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
742		self.into_key()
743	}
744
745	pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
746		match self {
747			Self::Index(v) => IndexedEntryValueRef::Index(v),
748			Self::Object(e) => IndexedEntryValueRef::Object(e.value()),
749		}
750	}
751
752	pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
753		self.into_value()
754	}
755
756	pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
757		match self {
758			Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
759			Self::Object(e) => {
760				let (k, v) = e.into_key_value();
761				(
762					IndexedEntryKeyRef::Object(k),
763					IndexedEntryValueRef::Object(v),
764				)
765			}
766		}
767	}
768
769	pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
770		self.into_key_value()
771	}
772}
773
774/// Try to convert from a JSON value directly into an expanded JSON-LD document
775/// without going through the expansion algorithm.
776///
777/// The input JSON value must be in expanded JSON-LD form.
778pub trait TryFromJson<T, B>: Sized {
779	fn try_from_json_in(
780		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
781		value: json_syntax::Value,
782	) -> Result<Self, InvalidExpandedJson>;
783}
784
785/// Try to convert from a JSON object directly into an expanded JSON-LD object
786/// without going through the expansion algorithm.
787///
788/// The input JSON object must be in expanded JSON-LD form.
789pub trait TryFromJsonObject<T, B>: Sized {
790	fn try_from_json_object_in(
791		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
792		object: json_syntax::Object,
793	) -> Result<Self, InvalidExpandedJson>;
794}
795
796impl<T, B, V: TryFromJson<T, B>> TryFromJson<T, B> for Vec<V> {
797	fn try_from_json_in(
798		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
799		value: json_syntax::Value,
800	) -> Result<Self, InvalidExpandedJson> {
801		match value {
802			json_syntax::Value::Array(items) => {
803				let mut result = Vec::new();
804
805				for item in items {
806					result.push(V::try_from_json_in(vocabulary, item)?)
807				}
808
809				Ok(result)
810			}
811			_ => Err(InvalidExpandedJson::InvalidList),
812		}
813	}
814}
815
816impl<T, B, V: Eq + Hash + TryFromJson<T, B>> TryFromJson<T, B> for IndexSet<V> {
817	fn try_from_json_in(
818		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
819		value: json_syntax::Value,
820	) -> Result<Self, InvalidExpandedJson> {
821		match value {
822			json_syntax::Value::Array(items) => {
823				let mut result = IndexSet::new();
824
825				for item in items {
826					result.insert(V::try_from_json_in(vocabulary, item)?);
827				}
828
829				Ok(result)
830			}
831			_ => Err(InvalidExpandedJson::InvalidList),
832		}
833	}
834}
835
836impl<T: Eq + Hash, B: Eq + Hash> TryFromJson<T, B> for Object<T, B> {
837	fn try_from_json_in(
838		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
839		value: json_syntax::Value,
840	) -> Result<Self, InvalidExpandedJson> {
841		match value {
842			json_syntax::Value::Object(object) => Self::try_from_json_object_in(vocabulary, object),
843			_ => Err(InvalidExpandedJson::InvalidObject),
844		}
845	}
846}
847
848impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Object<T, B> {
849	fn try_from_json_object_in(
850		vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
851		mut object: json_syntax::Object,
852	) -> Result<Self, InvalidExpandedJson> {
853		match object
854			.remove_unique("@context")
855			.map_err(InvalidExpandedJson::duplicate_key)?
856		{
857			Some(_) => Err(InvalidExpandedJson::NotExpanded),
858			None => {
859				if let Some(value_entry) = object
860					.remove_unique("@value")
861					.map_err(InvalidExpandedJson::duplicate_key)?
862				{
863					Ok(Self::Value(Value::try_from_json_object_in(
864						vocabulary,
865						object,
866						value_entry,
867					)?))
868				} else if let Some(list_entry) = object
869					.remove_unique("@list")
870					.map_err(InvalidExpandedJson::duplicate_key)?
871				{
872					Ok(Self::List(List::try_from_json_object_in(
873						vocabulary, object, list_entry,
874					)?))
875				} else {
876					let node = Node::try_from_json_object_in(vocabulary, object)?;
877					Ok(Self::node(node))
878				}
879			}
880		}
881	}
882}
883
884/// Invalid expanded JSON object error.
885///
886/// This can be raised when trying to directly convert a JSON value into an
887/// expanded JSON-LD object without using the expansion algorithm.
888#[derive(Debug)]
889pub enum InvalidExpandedJson {
890	InvalidObject,
891	InvalidList,
892	InvalidIndex,
893	InvalidId,
894	InvalidValueType,
895	InvalidLiteral,
896	InvalidLanguage,
897	InvalidDirection,
898	NotExpanded,
899	UnexpectedEntry,
900	DuplicateKey(json_syntax::object::Key),
901	Unexpected(json_syntax::Kind, json_syntax::Kind),
902}
903
904impl InvalidExpandedJson {
905	pub fn duplicate_key(
906		json_syntax::object::Duplicate(a, _): json_syntax::object::Duplicate<
907			json_syntax::object::Entry,
908		>,
909	) -> Self {
910		InvalidExpandedJson::DuplicateKey(a.key)
911	}
912}
913
914impl<T, B> Any<T, B> for Object<T, B> {
915	#[inline(always)]
916	fn as_ref(&self) -> Ref<T, B> {
917		match self {
918			Object::Value(value) => Ref::Value(value),
919			Object::Node(node) => Ref::Node(node),
920			Object::List(list) => Ref::List(list),
921		}
922	}
923}
924
925impl<T, B> From<Value<T>> for Object<T, B> {
926	#[inline(always)]
927	fn from(value: Value<T>) -> Self {
928		Self::Value(value)
929	}
930}
931
932impl<T, B> From<Node<T, B>> for Object<T, B> {
933	#[inline(always)]
934	fn from(node: Node<T, B>) -> Self {
935		Self::node(node)
936	}
937}
938
939/// Iterator through the types of an object.
940pub enum Types<'a, T, B> {
941	Value(Option<value::TypeRef<'a, T>>),
942	Node(std::slice::Iter<'a, Id<T, B>>),
943	List,
944}
945
946impl<'a, T, B> Iterator for Types<'a, T, B> {
947	type Item = TypeRef<'a, T, B>;
948
949	fn next(&mut self) -> Option<Self::Item> {
950		match self {
951			Self::Value(ty) => ty.take().map(TypeRef::from_value_type),
952			Self::Node(tys) => tys.next().map(TypeRef::from_reference),
953			Self::List => None,
954		}
955	}
956}
957
958/// Iterator through indexed objects.
959pub struct Objects<'a, T, B>(Option<std::slice::Iter<'a, IndexedObject<T, B>>>);
960
961impl<'a, T, B> Objects<'a, T, B> {
962	#[inline(always)]
963	pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedObject<T, B>>>) -> Self {
964		Self(inner)
965	}
966}
967
968impl<'a, T, B> Iterator for Objects<'a, T, B> {
969	type Item = &'a IndexedObject<T, B>;
970
971	#[inline(always)]
972	fn next(&mut self) -> Option<&'a IndexedObject<T, B>> {
973		match &mut self.0 {
974			None => None,
975			Some(it) => it.next(),
976		}
977	}
978}
979
980/// Object fragment.
981pub enum FragmentRef<'a, T, B> {
982	/// "@index" entry.
983	IndexEntry(&'a str),
984
985	/// "@index" entry key.
986	IndexKey,
987
988	/// "@index" entry value.
989	IndexValue(&'a str),
990
991	/// Object.
992	Object(&'a Object<T, B>),
993
994	/// Indexed object.
995	IndexedObject(&'a Indexed<Object<T, B>>),
996
997	/// Node object.
998	Node(&'a Node<T, B>),
999
1000	/// Indexed node object.
1001	IndexedNode(&'a IndexedNode<T, B>),
1002
1003	/// Indexed node list.
1004	IndexedNodeList(&'a [IndexedNode<T, B>]),
1005
1006	/// Value object fragment.
1007	ValueFragment(value::FragmentRef<'a, T>),
1008
1009	/// List object fragment.
1010	ListFragment(list::FragmentRef<'a, T, B>),
1011
1012	/// Node object fragment.
1013	NodeFragment(node::FragmentRef<'a, T, B>),
1014}
1015
1016impl<'a, T, B> FragmentRef<'a, T, B> {
1017	pub fn into_ref(self) -> Option<Ref<'a, T, B>> {
1018		match self {
1019			Self::Object(o) => Some(o.as_ref()),
1020			Self::IndexedObject(o) => Some(o.inner().as_ref()),
1021			Self::Node(n) => Some(n.as_ref()),
1022			Self::IndexedNode(n) => Some(n.inner().as_ref()),
1023			_ => None,
1024		}
1025	}
1026
1027	pub fn into_id(self) -> Option<Id<&'a T, &'a B>> {
1028		match self {
1029			Self::ValueFragment(i) => i.into_iri().map(Id::iri),
1030			Self::NodeFragment(i) => i.into_id().map(Into::into),
1031			_ => None,
1032		}
1033	}
1034
1035	pub fn as_id(&self) -> Option<Id<&'a T, &'a B>> {
1036		match self {
1037			Self::ValueFragment(i) => i.as_iri().map(Id::iri),
1038			Self::NodeFragment(i) => i.as_id().map(Into::into),
1039			_ => None,
1040		}
1041	}
1042
1043	pub fn is_json_array(&self) -> bool {
1044		match self {
1045			Self::IndexedNodeList(_) => true,
1046			Self::ValueFragment(i) => i.is_json_array(),
1047			Self::NodeFragment(n) => n.is_json_array(),
1048			_ => false,
1049		}
1050	}
1051
1052	pub fn is_json_object(&self) -> bool {
1053		match self {
1054			Self::Object(_) | Self::IndexedObject(_) | Self::Node(_) | Self::IndexedNode(_) => true,
1055			Self::ValueFragment(i) => i.is_json_array(),
1056			Self::NodeFragment(i) => i.is_json_array(),
1057			_ => false,
1058		}
1059	}
1060
1061	pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1062		match self {
1063			Self::IndexEntry(v) => SubFragments::IndexEntry(Some(()), Some(v)),
1064			Self::Object(o) => SubFragments::Object(None, o.sub_fragments()),
1065			Self::IndexedObject(o) => SubFragments::Object(o.index(), o.sub_fragments()),
1066			Self::Node(n) => SubFragments::Object(None, ObjectSubFragments::Node(n.entries())),
1067			Self::IndexedNode(n) => {
1068				SubFragments::Object(n.index(), ObjectSubFragments::Node(n.inner().entries()))
1069			}
1070			Self::IndexedNodeList(l) => SubFragments::IndexedNodeList(l.iter()),
1071			Self::ValueFragment(i) => SubFragments::Value(i.sub_fragments()),
1072			Self::NodeFragment(i) => SubFragments::Node(i.sub_fragments()),
1073			_ => SubFragments::None,
1074		}
1075	}
1076}
1077
1078pub enum ObjectSubFragments<'a, T, B> {
1079	List(Option<&'a [IndexedObject<T, B>]>),
1080	Value(value::Entries<'a, T>),
1081	Node(node::Entries<'a, T, B>),
1082}
1083
1084impl<'a, T, B> Iterator for ObjectSubFragments<'a, T, B> {
1085	type Item = FragmentRef<'a, T, B>;
1086
1087	fn next(&mut self) -> Option<Self::Item> {
1088		match self {
1089			Self::List(l) => l
1090				.take()
1091				.map(|e| FragmentRef::ListFragment(list::FragmentRef::Entry(e))),
1092			Self::Value(e) => e
1093				.next_back()
1094				.map(|e| FragmentRef::ValueFragment(value::FragmentRef::Entry(e))),
1095			Self::Node(e) => e
1096				.next()
1097				.map(|e| FragmentRef::NodeFragment(node::FragmentRef::Entry(e))),
1098		}
1099	}
1100}
1101
1102pub enum SubFragments<'a, T, B> {
1103	None,
1104	IndexEntry(Option<()>, Option<&'a str>),
1105	Object(Option<&'a str>, ObjectSubFragments<'a, T, B>),
1106	Value(value::SubFragments<'a, T>),
1107	Node(node::SubFragments<'a, T, B>),
1108	IndexedNodeList(std::slice::Iter<'a, IndexedNode<T, B>>),
1109}
1110
1111impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1112	type Item = FragmentRef<'a, T, B>;
1113
1114	fn next(&mut self) -> Option<Self::Item> {
1115		match self {
1116			Self::None => None,
1117			Self::IndexEntry(k, v) => k
1118				.take()
1119				.map(|()| FragmentRef::IndexKey)
1120				.or_else(|| v.take().map(FragmentRef::IndexValue)),
1121			Self::Object(index, i) => match index.take() {
1122				Some(index) => Some(FragmentRef::IndexEntry(index)),
1123				None => i.next(),
1124			},
1125			Self::Value(i) => i.next().map(FragmentRef::ValueFragment),
1126			Self::Node(i) => i.next(),
1127			Self::IndexedNodeList(i) => i.next().map(FragmentRef::IndexedNode),
1128		}
1129	}
1130}
1131
1132pub struct Traverse<'a, T, B> {
1133	stack: SmallVec<[FragmentRef<'a, T, B>; 8]>,
1134}
1135
1136impl<'a, T, B> Traverse<'a, T, B> {
1137	pub(crate) fn new(items: impl IntoIterator<Item = FragmentRef<'a, T, B>>) -> Self {
1138		let stack = items.into_iter().collect();
1139		Self { stack }
1140	}
1141}
1142
1143impl<'a, T, B> Iterator for Traverse<'a, T, B> {
1144	type Item = FragmentRef<'a, T, B>;
1145
1146	fn next(&mut self) -> Option<Self::Item> {
1147		match self.stack.pop() {
1148			Some(item) => {
1149				self.stack.extend(item.sub_fragments());
1150				Some(item)
1151			}
1152			None => None,
1153		}
1154	}
1155}
1156
1157impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Object<T, B> {
1158	fn into_json_with(self, vocabulary: &N) -> json_syntax::Value {
1159		match self {
1160			Self::Value(v) => v.into_json_with(vocabulary),
1161			Self::Node(n) => n.into_json_with(vocabulary),
1162			Self::List(l) => l.into_json_with(vocabulary),
1163		}
1164	}
1165}