1use crate::{HashMap, Id, IndexSet, Indexed, LenientLangTag, Relabel, ValidId};
3use contextual::{IntoRefWithContext, WithContext};
4use derive_where::derive_where;
5use iri_rs::IriBuf;
6use jsonld_syntax::{IntoJsonWithContext, Keyword};
7use jstrict::Number;
8use rdfx::{
9 BlankIdBuf,
10 LocalGenerator,
11 vocabulary::{Vocabulary, VocabularyMut},
12};
13use smallvec::SmallVec;
14use std::hash::Hash;
15
16mod dismantle;
18pub mod list;
19mod mapped_eq;
20pub mod node;
22mod typ;
23pub mod value;
25
26pub use list::List;
27pub use mapped_eq::MappedEq;
28pub use node::{Graph, IndexedNode, Node, NodeParts, Nodes};
29pub use typ::{Type, TypeRef};
30pub use value::{Literal, Value};
31
32pub trait Any<T, B> {
34 fn as_ref(&self) -> Ref<'_, T, B>;
36
37 #[inline]
38 fn id(&self) -> Option<&Id<T, B>> {
41 match self.as_ref() {
42 Ref::Node(n) => n.id.as_ref(),
43 _ => None,
44 }
45 }
46
47 #[inline]
48 fn language<'a>(&'a self) -> Option<&'a LenientLangTag>
50 where
51 T: 'a,
52 B: 'a,
53 {
54 match self.as_ref() {
55 Ref::Value(value) => value.language(),
56 _ => None,
57 }
58 }
59
60 #[inline]
61 fn is_value(&self) -> bool {
63 matches!(self.as_ref(), Ref::Value(_))
64 }
65
66 #[inline]
67 fn is_node(&self) -> bool {
69 matches!(self.as_ref(), Ref::Node(_))
70 }
71
72 #[inline]
73 fn is_graph(&self) -> bool {
76 match self.as_ref() {
77 Ref::Node(n) => n.is_graph(),
78 _ => false,
79 }
80 }
81
82 #[inline]
83 fn is_list(&self) -> bool {
85 matches!(self.as_ref(), Ref::List(_))
86 }
87}
88
89pub enum Ref<'a, T, B> {
91 Value(&'a Value<T>),
93
94 Node(&'a Node<T, B>),
96
97 List(&'a List<T, B>),
99}
100
101pub type IndexedObject<T, B = ()> = Indexed<Object<T, B>>;
103
104#[allow(clippy::derived_hash_with_manual_eq)]
113#[derive(Debug, Clone, Hash)]
114#[derive_where(PartialEq; T: Eq + Hash, B: Eq + Hash)]
115pub enum Object<T = IriBuf, B = BlankIdBuf> {
116 Value(Value<T>),
118
119 Node(Box<Node<T, B>>),
121
122 List(List<T, B>),
124}
125
126impl<T: Eq + Hash, B: Eq + Hash> Eq for Object<T, B> {}
127
128impl<T, B> Object<T, B> {
129 #[inline(always)]
131 #[must_use]
132 pub fn null() -> Self {
133 Self::Value(Value::null())
134 }
135
136 #[inline(always)]
138 pub fn node(n: Node<T, B>) -> Self {
139 Self::Node(Box::new(n))
140 }
141
142 #[inline(always)]
144 pub fn id(&self) -> Option<&Id<T, B>> {
145 match self {
146 Object::Node(n) => n.id.as_ref(),
147 _ => None,
148 }
149 }
150
151 pub fn identify_all_with<V: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
157 &mut self,
158 vocabulary: &mut V,
159 generator: &mut G,
160 ) -> Result<(), crate::id::GeneratedIdError>
161 where
162 T: Eq + Hash,
163 B: Eq + Hash,
164 {
165 match self {
166 Object::Node(n) => n.identify_all_with(vocabulary, generator)?,
167 Object::List(l) => {
168 for object in l {
169 object.identify_all_with(vocabulary, generator)?;
170 }
171 }
172 Object::Value(_) => (),
173 }
174 Ok(())
175 }
176
177 pub fn identify_all<G: LocalGenerator>(&mut self, generator: &mut G) -> Result<(), crate::id::GeneratedIdError>
184 where
185 T: Eq + Hash,
186 B: Eq + Hash,
187 (): Vocabulary<Iri = T, BlankId = B>,
188 {
189 self.identify_all_with(&mut (), generator)
190 }
191
192 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
195 match self {
196 Self::List(l) => l.canonicalize_with(buffer),
197 Self::Node(n) => n.canonicalize_with(buffer),
198 Self::Value(v) => v.canonicalize_with(buffer),
199 }
200 }
201
202 pub fn canonicalize(&mut self) {
204 let mut buffer = ryu_js::Buffer::new();
205 self.canonicalize_with(&mut buffer);
206 }
207
208 pub fn types(&self) -> Types<'_, T, B> {
210 match self {
211 Self::Value(value) => Types::Value(value.typ()),
212 Self::Node(node) => Types::Node(node.types().iter()),
213 Self::List(_) => Types::List,
214 }
215 }
216
217 #[inline(always)]
222 pub fn as_iri(&self) -> Option<&T> {
223 match self {
224 Object::Node(node) => node.as_iri(),
225 _ => None,
226 }
227 }
228
229 #[inline(always)]
231 pub fn is_value(&self) -> bool {
232 matches!(self, Object::Value(_))
233 }
234
235 #[inline(always)]
237 pub fn as_value(&self) -> Option<&Value<T>> {
238 match self {
239 Self::Value(v) => Some(v),
240 _ => None,
241 }
242 }
243
244 #[inline(always)]
246 pub fn as_value_mut(&mut self) -> Option<&mut Value<T>> {
247 match self {
248 Self::Value(v) => Some(v),
249 _ => None,
250 }
251 }
252
253 #[inline(always)]
255 pub fn into_value(self) -> Option<Value<T>> {
256 match self {
257 Self::Value(v) => Some(v),
258 _ => None,
259 }
260 }
261
262 #[inline(always)]
264 pub fn is_node(&self) -> bool {
265 matches!(self, Object::Node(_))
266 }
267
268 #[inline(always)]
270 pub fn as_node(&self) -> Option<&Node<T, B>> {
271 match self {
272 Self::Node(n) => Some(n),
273 _ => None,
274 }
275 }
276
277 #[inline(always)]
279 pub fn as_node_mut(&mut self) -> Option<&mut Node<T, B>> {
280 match self {
281 Self::Node(n) => Some(n),
282 _ => None,
283 }
284 }
285
286 #[inline(always)]
288 pub fn into_node(self) -> Option<Node<T, B>> {
289 match self {
290 Self::Node(n) => Some(*n),
291 _ => None,
292 }
293 }
294
295 #[inline(always)]
297 pub fn is_graph(&self) -> bool {
298 match self {
299 Object::Node(n) => n.is_graph(),
300 _ => false,
301 }
302 }
303
304 #[inline(always)]
306 pub fn is_list(&self) -> bool {
307 matches!(self, Object::List(_))
308 }
309
310 #[inline(always)]
312 pub fn as_list(&self) -> Option<&List<T, B>> {
313 match self {
314 Self::List(l) => Some(l),
315 _ => None,
316 }
317 }
318
319 #[inline(always)]
321 pub fn as_list_mut(&mut self) -> Option<&mut List<T, B>> {
322 match self {
323 Self::List(l) => Some(l),
324 _ => None,
325 }
326 }
327
328 #[inline(always)]
330 pub fn into_list(self) -> Option<List<T, B>> {
331 match self {
332 Self::List(l) => Some(l),
333 _ => None,
334 }
335 }
336
337 #[inline(always)]
343 pub fn as_str(&self) -> Option<&str>
344 where
345 T: AsRef<str>,
346 B: AsRef<str>,
347 {
348 match self {
349 Object::Value(value) => value.as_str(),
350 Object::Node(node) => node.as_str(),
351 Object::List(_) => None,
352 }
353 }
354
355 #[inline(always)]
357 pub fn as_bool(&self) -> Option<bool> {
358 match self {
359 Object::Value(value) => value.as_bool(),
360 _ => None,
361 }
362 }
363
364 #[inline(always)]
366 pub fn as_number(&self) -> Option<&Number> {
367 match self {
368 Object::Value(value) => value.as_number(),
369 _ => None,
370 }
371 }
372
373 #[inline(always)]
376 pub fn language(&self) -> Option<&LenientLangTag> {
377 match self {
378 Object::Value(value) => value.language(),
379 _ => None,
380 }
381 }
382
383 pub fn traverse(&self) -> Traverse<'_, T, B> {
392 Traverse::new(Some(FragmentRef::Object(self)))
393 }
394
395 fn sub_fragments(&self) -> ObjectSubFragments<'_, T, B> {
396 match self {
397 Self::Value(v) => ObjectSubFragments::Value(v.entries()),
398 Self::List(l) => ObjectSubFragments::List(Some(l.entry())),
399 Self::Node(n) => ObjectSubFragments::Node(n.entries()),
400 }
401 }
402
403 pub fn equivalent(&self, other: &Self) -> bool
409 where
410 T: Eq + Hash,
411 B: Eq + Hash,
412 {
413 match (self, other) {
414 (Self::Value(a), Self::Value(b)) => a == b,
415 (Self::Node(a), Self::Node(b)) => a.equivalent(b),
416 _ => false,
417 }
418 }
419
420 pub fn entries(&self) -> Entries<'_, T, B> {
423 match self {
424 Self::Value(value) => Entries::Value(value.entries()),
425 Self::List(list) => Entries::List(Some(list.entry())),
426 Self::Node(node) => Entries::Node(node.entries()),
427 }
428 }
429
430 pub fn map_ids<U, C>(self, mut map_iri: impl FnMut(T) -> U, mut map_id: impl FnMut(Id<T, B>) -> Id<U, C>) -> Object<U, C>
433 where
434 U: Eq + Hash,
435 C: Eq + Hash,
436 {
437 self.map_ids_with(&mut map_iri, &mut map_id)
438 }
439
440 fn map_ids_with<U, C>(self, map_iri: &mut impl FnMut(T) -> U, map_id: &mut impl FnMut(Id<T, B>) -> Id<U, C>) -> Object<U, C>
441 where
442 U: Eq + Hash,
443 C: Eq + Hash,
444 {
445 match self {
446 Self::Value(value) => Object::Value(value.map_ids(map_iri)),
447 Self::List(list) => Object::List(list.map_ids_with(map_iri, map_id)),
448 Self::Node(node) => Object::Node(Box::new((*node).map_ids_with(map_iri, map_id))),
449 }
450 }
451}
452
453impl<T, B> Relabel<T, B> for Object<T, B> {
454 fn relabel_with<N: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
455 &mut self,
456 vocabulary: &mut N,
457 generator: &mut G,
458 relabeling: &mut HashMap<B, ValidId<T, B>>,
459 ) -> Result<(), crate::id::GeneratedIdError>
460 where
461 T: Clone + Eq + Hash,
462 B: Clone + Eq + Hash,
463 {
464 match self {
465 Self::Node(n) => n.relabel_with(vocabulary, generator, relabeling),
466 Self::List(l) => l.relabel_with(vocabulary, generator, relabeling),
467 Self::Value(_) => Ok(()),
468 }
469 }
470}
471
472impl<T: Eq + Hash, B: Eq + Hash> Indexed<Object<T, B>> {
473 pub fn equivalent(&self, other: &Self) -> bool {
476 self.index() == other.index() && self.inner().equivalent(other.inner())
477 }
478}
479
480impl<T, B> Indexed<Object<T, B>> {
481 #[inline(always)]
483 pub fn into_indexed_node(self) -> Option<Indexed<Node<T, B>>> {
484 let (object, index) = self.into_parts();
485 object.into_node().map(|node| Indexed::new(node, index))
486 }
487
488 #[inline(always)]
490 pub fn into_indexed_value(self) -> Option<Indexed<Value<T>>> {
491 let (object, index) = self.into_parts();
492 object.into_value().map(|value| Indexed::new(value, index))
493 }
494
495 #[inline(always)]
497 pub fn into_indexed_list(self) -> Option<Indexed<List<T, B>>> {
498 let (object, index) = self.into_parts();
499 object.into_list().map(|list| Indexed::new(list, index))
500 }
501
502 pub fn into_unnamed_graph(self) -> Result<Graph<T, B>, Self> {
508 let (obj, index) = self.into_parts();
509 match obj {
510 Object::Node(n) => match n.into_unnamed_graph() {
511 Ok(g) => Ok(g),
512 Err(n) => Err(Indexed::new(Object::Node(n), index)),
513 },
514 obj => Err(Indexed::new(obj, index)),
515 }
516 }
517
518 pub fn entries(&self) -> IndexedEntries<'_, T, B> {
521 IndexedEntries {
522 index: self.index(),
523 inner: self.inner().entries(),
524 }
525 }
526}
527
528#[derive_where(Clone)]
529pub enum Entries<'a, T, B> {
531 Value(value::Entries<'a, T>),
533 List(Option<&'a [IndexedObject<T, B>]>),
535 Node(node::Entries<'a, T, B>),
537}
538
539impl<'a, T, B> Iterator for Entries<'a, T, B> {
540 type Item = EntryRef<'a, T, B>;
541
542 fn size_hint(&self) -> (usize, Option<usize>) {
543 let len = match self {
544 Self::Value(v) => v.len(),
545 Self::List(l) => usize::from(l.is_some()),
546 Self::Node(n) => n.len(),
547 };
548
549 (len, Some(len))
550 }
551
552 fn next(&mut self) -> Option<Self::Item> {
553 match self {
554 Self::Value(v) => v.next().map(EntryRef::Value),
555 Self::List(l) => l.take().map(EntryRef::List),
556 Self::Node(n) => n.next().map(EntryRef::Node),
557 }
558 }
559}
560
561impl<T, B> ExactSizeIterator for Entries<'_, T, B> {}
562
563#[derive_where(Clone)]
564pub struct IndexedEntries<'a, T, B> {
566 index: Option<&'a str>,
567 inner: Entries<'a, T, B>,
568}
569
570impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
571 type Item = IndexedEntryRef<'a, T, B>;
572
573 fn size_hint(&self) -> (usize, Option<usize>) {
574 let len = self.inner.len() + usize::from(self.index.is_some());
575 (len, Some(len))
576 }
577
578 fn next(&mut self) -> Option<Self::Item> {
579 self.index
580 .take()
581 .map(IndexedEntryRef::Index)
582 .or_else(|| self.inner.next().map(IndexedEntryRef::Object))
583 }
584}
585
586impl<T, B> ExactSizeIterator for IndexedEntries<'_, T, B> {}
587
588#[derive(PartialEq, Eq)]
594#[derive_where(Clone, Copy)]
595pub enum EntryKeyRef<'a, T, B> {
597 Value(value::EntryKey),
599 List,
601 Node(node::EntryKeyRef<'a, T, B>),
603}
604
605impl<'a, T, B> EntryKeyRef<'a, T, B> {
606 #[must_use]
608 pub fn into_keyword(self) -> Option<Keyword> {
609 match self {
610 Self::Value(e) => Some(e.into_keyword()),
611 Self::List => Some(Keyword::List),
612 Self::Node(e) => e.into_keyword(),
613 }
614 }
615
616 #[must_use]
618 pub fn as_keyword(&self) -> Option<Keyword> {
619 self.into_keyword()
620 }
621
622 #[must_use]
624 pub fn into_str(self) -> &'a str
625 where
626 T: AsRef<str>,
627 B: AsRef<str>,
628 {
629 match self {
630 Self::Value(e) => e.into_str(),
631 Self::List => "@list",
632 Self::Node(e) => e.into_str(),
633 }
634 }
635
636 #[must_use]
638 pub fn as_str(self) -> &'a str
639 where
640 T: AsRef<str>,
641 B: AsRef<str>,
642 {
643 self.into_str()
644 }
645}
646
647impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for EntryKeyRef<'a, T, B> {
648 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
649 match self {
650 EntryKeyRef::Value(e) => e.into_str(),
651 EntryKeyRef::List => "@list",
652 EntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
653 }
654 }
655}
656
657#[derive_where(Clone, Copy)]
658pub enum EntryValueRef<'a, T, B> {
660 Value(value::EntryRef<'a, T>),
662 List(&'a [IndexedObject<T, B>]),
664 Node(node::EntryValueRef<'a, T, B>),
666}
667
668#[derive_where(Clone, Copy)]
669pub enum EntryRef<'a, T, B> {
671 Value(value::EntryRef<'a, T>),
673 List(&'a [IndexedObject<T, B>]),
675 Node(node::EntryRef<'a, T, B>),
677}
678
679impl<'a, T, B> EntryRef<'a, T, B> {
680 #[must_use]
682 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
683 match self {
684 Self::Value(e) => EntryKeyRef::Value(e.key()),
685 Self::List(_) => EntryKeyRef::List,
686 Self::Node(e) => EntryKeyRef::Node(e.key()),
687 }
688 }
689
690 #[must_use]
692 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
693 self.into_key()
694 }
695
696 #[must_use]
698 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
699 match self {
700 Self::Value(v) => EntryValueRef::Value(v),
701 Self::List(v) => EntryValueRef::List(v),
702 Self::Node(e) => EntryValueRef::Node(e.value()),
703 }
704 }
705
706 #[must_use]
708 pub fn value(&self) -> EntryValueRef<'a, T, B> {
709 self.into_value()
710 }
711
712 #[must_use]
714 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
715 match self {
716 Self::Value(e) => (EntryKeyRef::Value(e.key()), EntryValueRef::Value(e)),
717 Self::List(e) => (EntryKeyRef::List, EntryValueRef::List(e)),
718 Self::Node(e) => {
719 let (k, v) = e.into_key_value();
720 (EntryKeyRef::Node(k), EntryValueRef::Node(v))
721 }
722 }
723 }
724
725 #[must_use]
727 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
728 self.into_key_value()
729 }
730}
731
732#[derive(PartialEq, Eq)]
733#[derive_where(Clone, Copy)]
734pub enum IndexedEntryKeyRef<'a, T, B> {
736 Index,
738 Object(EntryKeyRef<'a, T, B>),
740}
741
742impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
743 #[must_use]
745 pub fn into_keyword(self) -> Option<Keyword> {
746 match self {
747 Self::Index => Some(Keyword::Index),
748 Self::Object(e) => e.into_keyword(),
749 }
750 }
751
752 #[must_use]
754 pub fn as_keyword(&self) -> Option<Keyword> {
755 self.into_keyword()
756 }
757
758 #[must_use]
760 pub fn into_str(self) -> &'a str
761 where
762 T: AsRef<str>,
763 B: AsRef<str>,
764 {
765 match self {
766 Self::Index => "@index",
767 Self::Object(e) => e.into_str(),
768 }
769 }
770
771 #[must_use]
773 pub fn as_str(&self) -> &'a str
774 where
775 T: AsRef<str>,
776 B: AsRef<str>,
777 {
778 self.into_str()
779 }
780}
781
782impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for IndexedEntryKeyRef<'a, T, B> {
783 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
784 match self {
785 IndexedEntryKeyRef::Index => "@index",
786 IndexedEntryKeyRef::Object(e) => e.into_with(vocabulary).into_str(),
787 }
788 }
789}
790
791#[derive_where(Clone, Copy)]
792pub enum IndexedEntryValueRef<'a, T, B> {
794 Index(&'a str),
796 Object(EntryValueRef<'a, T, B>),
798}
799
800#[derive_where(Clone, Copy)]
801pub enum IndexedEntryRef<'a, T, B> {
803 Index(&'a str),
805 Object(EntryRef<'a, T, B>),
807}
808
809impl<'a, T, B> IndexedEntryRef<'a, T, B> {
810 #[must_use]
812 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
813 match self {
814 Self::Index(_) => IndexedEntryKeyRef::Index,
815 Self::Object(e) => IndexedEntryKeyRef::Object(e.key()),
816 }
817 }
818
819 #[must_use]
821 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
822 self.into_key()
823 }
824
825 #[must_use]
827 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
828 match self {
829 Self::Index(v) => IndexedEntryValueRef::Index(v),
830 Self::Object(e) => IndexedEntryValueRef::Object(e.value()),
831 }
832 }
833
834 #[must_use]
836 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
837 self.into_value()
838 }
839
840 #[must_use]
842 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
843 match self {
844 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
845 Self::Object(e) => {
846 let (k, v) = e.into_key_value();
847 (IndexedEntryKeyRef::Object(k), IndexedEntryValueRef::Object(v))
848 }
849 }
850 }
851
852 #[must_use]
854 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
855 self.into_key_value()
856 }
857}
858
859pub trait TryFromJson<T, B>: Sized {
868 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson>;
875}
876
877pub trait TryFromJsonObject<T, B>: Sized {
882 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, object: jstrict::Object) -> Result<Self, InvalidExpandedJson>;
889}
890
891impl<T, B, V: TryFromJson<T, B>> TryFromJson<T, B> for Vec<V> {
892 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
893 match value {
894 jstrict::Value::Array(items) => {
895 let mut result = Vec::new();
896
897 for item in items {
898 result.push(V::try_from_json_in(vocabulary, item)?);
899 }
900
901 Ok(result)
902 }
903 _ => Err(InvalidExpandedJson::InvalidList),
904 }
905 }
906}
907
908impl<T, B, V: Eq + Hash + TryFromJson<T, B>> TryFromJson<T, B> for IndexSet<V> {
909 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
910 match value {
911 jstrict::Value::Array(items) => {
912 let mut result = IndexSet::default();
913
914 for item in items {
915 result.insert(V::try_from_json_in(vocabulary, item)?);
916 }
917
918 Ok(result)
919 }
920 _ => Err(InvalidExpandedJson::InvalidList),
921 }
922 }
923}
924
925impl<T: Eq + Hash, B: Eq + Hash> TryFromJson<T, B> for Object<T, B> {
926 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
927 match value {
928 jstrict::Value::Object(object) => Self::try_from_json_object_in(vocabulary, object),
929 _ => Err(InvalidExpandedJson::InvalidObject),
930 }
931 }
932}
933
934impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Object<T, B> {
935 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, mut object: jstrict::Object) -> Result<Self, InvalidExpandedJson> {
936 match object.remove_unique("@context").map_err(InvalidExpandedJson::duplicate_key)? {
937 Some(_) => Err(InvalidExpandedJson::NotExpanded),
938 None => {
939 if let Some(value_entry) = object.remove_unique("@value").map_err(InvalidExpandedJson::duplicate_key)? {
940 Ok(Self::Value(Value::try_from_json_object_in(vocabulary, object, value_entry)?))
941 } else if let Some(list_entry) = object.remove_unique("@list").map_err(InvalidExpandedJson::duplicate_key)? {
942 Ok(Self::List(List::try_from_json_object_in(vocabulary, object, list_entry)?))
943 } else {
944 let node = Node::try_from_json_object_in(vocabulary, object)?;
945 Ok(Self::node(node))
946 }
947 }
948 }
949 }
950}
951
952#[derive(Debug, thiserror::Error)]
957pub enum InvalidExpandedJson {
958 #[error("invalid object")]
960 InvalidObject,
961 #[error("invalid `@list` value")]
963 InvalidList,
964 #[error("invalid `@index` value")]
966 InvalidIndex,
967 #[error("invalid `@id` value")]
969 InvalidId,
970 #[error("invalid `@type` value")]
972 InvalidValueType,
973 #[error("invalid literal")]
975 InvalidLiteral,
976 #[error("invalid `@language` value")]
978 InvalidLanguage,
979 #[error("invalid `@direction` value")]
981 InvalidDirection,
982 #[error("invalid language-tagged string")]
984 InvalidLangString,
985 #[error("not an expanded document")]
987 NotExpanded,
988 #[error("unexpected entry")]
990 UnexpectedEntry,
991 #[error("duplicate key `{0}`")]
993 DuplicateKey(jstrict::object::Key),
994 #[error("unexpected {0}, expected {1}")]
996 Unexpected(jstrict::Kind, jstrict::Kind),
997}
998
999impl InvalidExpandedJson {
1000 #[must_use]
1002 pub fn duplicate_key(jstrict::object::Duplicate(a, _): jstrict::object::Duplicate<jstrict::object::Entry>) -> Self {
1003 InvalidExpandedJson::DuplicateKey(a.key)
1004 }
1005}
1006
1007impl<T, B> Any<T, B> for Object<T, B> {
1008 #[inline(always)]
1009 fn as_ref(&self) -> Ref<'_, T, B> {
1010 match self {
1011 Object::Value(value) => Ref::Value(value),
1012 Object::Node(node) => Ref::Node(node),
1013 Object::List(list) => Ref::List(list),
1014 }
1015 }
1016}
1017
1018impl<T, B> From<Value<T>> for Object<T, B> {
1019 #[inline(always)]
1020 fn from(value: Value<T>) -> Self {
1021 Self::Value(value)
1022 }
1023}
1024
1025impl<T, B> From<Node<T, B>> for Object<T, B> {
1026 #[inline(always)]
1027 fn from(node: Node<T, B>) -> Self {
1028 Self::node(node)
1029 }
1030}
1031
1032pub enum Types<'a, T, B> {
1034 Value(Option<value::TypeRef<'a, T>>),
1036 Node(std::slice::Iter<'a, Id<T, B>>),
1038 List,
1040}
1041
1042impl<'a, T, B> Iterator for Types<'a, T, B> {
1043 type Item = TypeRef<'a, T, B>;
1044
1045 fn next(&mut self) -> Option<Self::Item> {
1046 match self {
1047 Self::Value(ty) => ty.take().map(TypeRef::from_value_type),
1048 Self::Node(tys) => tys.next().map(TypeRef::from_reference),
1049 Self::List => None,
1050 }
1051 }
1052}
1053
1054pub struct Objects<'a, T, B>(Option<std::slice::Iter<'a, IndexedObject<T, B>>>);
1056
1057impl<'a, T, B> Objects<'a, T, B> {
1058 #[inline(always)]
1059 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedObject<T, B>>>) -> Self {
1060 Self(inner)
1061 }
1062}
1063
1064impl<'a, T, B> Iterator for Objects<'a, T, B> {
1065 type Item = &'a IndexedObject<T, B>;
1066
1067 #[inline(always)]
1068 fn next(&mut self) -> Option<&'a IndexedObject<T, B>> {
1069 match &mut self.0 {
1070 None => None,
1071 Some(it) => it.next(),
1072 }
1073 }
1074}
1075
1076pub enum FragmentRef<'a, T, B> {
1078 IndexEntry(&'a str),
1080
1081 IndexKey,
1083
1084 IndexValue(&'a str),
1086
1087 Object(&'a Object<T, B>),
1089
1090 IndexedObject(&'a Indexed<Object<T, B>>),
1092
1093 Node(&'a Node<T, B>),
1095
1096 IndexedNode(&'a IndexedNode<T, B>),
1098
1099 IndexedNodeList(&'a [IndexedNode<T, B>]),
1101
1102 ValueFragment(value::FragmentRef<'a, T>),
1104
1105 ListFragment(list::FragmentRef<'a, T, B>),
1107
1108 NodeFragment(node::FragmentRef<'a, T, B>),
1110}
1111
1112impl<'a, T, B> FragmentRef<'a, T, B> {
1113 #[must_use]
1115 pub fn into_ref(self) -> Option<Ref<'a, T, B>> {
1116 match self {
1117 Self::Object(o) => Some(o.as_ref()),
1118 Self::IndexedObject(o) => Some(o.inner().as_ref()),
1119 Self::Node(n) => Some(n.as_ref()),
1120 Self::IndexedNode(n) => Some(n.inner().as_ref()),
1121 _ => None,
1122 }
1123 }
1124
1125 pub fn into_id(self) -> Option<Id<&'a T, &'a B>> {
1127 match self {
1128 Self::ValueFragment(i) => i.into_iri().map(Id::iri),
1129 Self::NodeFragment(i) => i.into_id().map(Into::into),
1130 _ => None,
1131 }
1132 }
1133
1134 pub fn as_id(&self) -> Option<Id<&'a T, &'a B>> {
1136 match self {
1137 Self::ValueFragment(i) => i.as_iri().map(Id::iri),
1138 Self::NodeFragment(i) => i.as_id().map(Into::into),
1139 _ => None,
1140 }
1141 }
1142
1143 #[must_use]
1145 pub fn is_json_array(&self) -> bool {
1146 match self {
1147 Self::IndexedNodeList(_) => true,
1148 Self::ValueFragment(i) => i.is_json_array(),
1149 Self::NodeFragment(n) => n.is_json_array(),
1150 _ => false,
1151 }
1152 }
1153
1154 #[must_use]
1156 pub fn is_json_object(&self) -> bool {
1157 match self {
1158 Self::Object(_) | Self::IndexedObject(_) | Self::Node(_) | Self::IndexedNode(_) => true,
1159 Self::ValueFragment(i) => i.is_json_object(),
1160 Self::NodeFragment(i) => i.is_json_object(),
1161 _ => false,
1162 }
1163 }
1164
1165 #[must_use]
1167 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1168 match self {
1169 Self::IndexEntry(v) => SubFragments::IndexEntry(Some(()), Some(v)),
1170 Self::Object(o) => SubFragments::Object(None, o.sub_fragments()),
1171 Self::IndexedObject(o) => SubFragments::Object(o.index(), o.sub_fragments()),
1172 Self::Node(n) => SubFragments::Object(None, ObjectSubFragments::Node(n.entries())),
1173 Self::IndexedNode(n) => SubFragments::Object(n.index(), ObjectSubFragments::Node(n.inner().entries())),
1174 Self::IndexedNodeList(l) => SubFragments::IndexedNodeList(l.iter()),
1175 Self::ValueFragment(i) => SubFragments::Value(i.sub_fragments()),
1176 Self::NodeFragment(i) => SubFragments::Node(i.sub_fragments()),
1177 Self::ListFragment(l) => SubFragments::List(l.sub_fragments()),
1178 Self::IndexKey | Self::IndexValue(_) => SubFragments::None,
1179 }
1180 }
1181}
1182
1183pub enum ObjectSubFragments<'a, T, B> {
1185 List(Option<&'a [IndexedObject<T, B>]>),
1187 Value(value::Entries<'a, T>),
1189 Node(node::Entries<'a, T, B>),
1191}
1192
1193impl<'a, T, B> Iterator for ObjectSubFragments<'a, T, B> {
1194 type Item = FragmentRef<'a, T, B>;
1195
1196 fn next(&mut self) -> Option<Self::Item> {
1197 match self {
1198 Self::List(l) => l.take().map(|e| FragmentRef::ListFragment(list::FragmentRef::Entry(e))),
1199 Self::Value(e) => e.next_back().map(|e| FragmentRef::ValueFragment(value::FragmentRef::Entry(e))),
1200 Self::Node(e) => e.next().map(|e| FragmentRef::NodeFragment(node::FragmentRef::Entry(e))),
1201 }
1202 }
1203}
1204
1205pub enum SubFragments<'a, T, B> {
1207 None,
1209 IndexEntry(Option<()>, Option<&'a str>),
1211 Object(Option<&'a str>, ObjectSubFragments<'a, T, B>),
1213 Value(value::SubFragments<'a, T>),
1215 Node(node::SubFragments<'a, T, B>),
1217 List(list::SubFragments<'a, T, B>),
1219 IndexedNodeList(std::slice::Iter<'a, IndexedNode<T, B>>),
1221}
1222
1223impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1224 type Item = FragmentRef<'a, T, B>;
1225
1226 fn next(&mut self) -> Option<Self::Item> {
1227 match self {
1228 Self::None => None,
1229 Self::IndexEntry(k, v) => k.take().map(|()| FragmentRef::IndexKey).or_else(|| v.take().map(FragmentRef::IndexValue)),
1230 Self::Object(index, i) => match index.take() {
1231 Some(index) => Some(FragmentRef::IndexEntry(index)),
1232 None => i.next(),
1233 },
1234 Self::Value(i) => i.next().map(FragmentRef::ValueFragment),
1235 Self::Node(i) => i.next(),
1236 Self::List(i) => i.next(),
1237 Self::IndexedNodeList(i) => i.next().map(FragmentRef::IndexedNode),
1238 }
1239 }
1240}
1241
1242pub struct Traverse<'a, T, B> {
1244 stack: SmallVec<[FragmentRef<'a, T, B>; 8]>,
1245}
1246
1247impl<'a, T, B> Traverse<'a, T, B> {
1248 pub(crate) fn new(items: impl IntoIterator<Item = FragmentRef<'a, T, B>>) -> Self {
1249 let stack = items.into_iter().collect();
1250 Self { stack }
1251 }
1252}
1253
1254impl<'a, T, B> Iterator for Traverse<'a, T, B> {
1255 type Item = FragmentRef<'a, T, B>;
1256
1257 fn next(&mut self) -> Option<Self::Item> {
1258 match self.stack.pop() {
1259 Some(item) => {
1260 self.stack.extend(item.sub_fragments());
1261 Some(item)
1262 }
1263 None => None,
1264 }
1265 }
1266}
1267
1268impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Object<T, B> {
1269 fn into_json_with(self, vocabulary: &N) -> jstrict::Value {
1270 match self {
1271 Self::Value(v) => v.into_json_with(vocabulary),
1272 Self::Node(n) => n.into_json_with(vocabulary),
1273 Self::List(l) => l.into_json_with(vocabulary),
1274 }
1275 }
1276}