1use crate::{HashMap, Id, IndexSet, Indexed, LenientLangTag, Relabel, ValidId};
3use contextual::{IntoRefWithContext, WithContext};
4use educe::Educe;
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
16pub mod list;
18mod mapped_eq;
19pub mod node;
21mod typ;
22pub mod value;
24
25pub use list::List;
26pub use mapped_eq::MappedEq;
27pub use node::{Graph, IndexedNode, Node, Nodes};
28pub use typ::{Type, TypeRef};
29pub use value::{Literal, Value};
30
31pub trait Any<T, B> {
33 fn as_ref(&self) -> Ref<'_, T, B>;
35
36 #[inline]
37 fn id(&self) -> Option<&Id<T, B>> {
40 match self.as_ref() {
41 Ref::Node(n) => n.id.as_ref(),
42 _ => None,
43 }
44 }
45
46 #[inline]
47 fn language<'a>(&'a self) -> Option<&'a LenientLangTag>
49 where
50 T: 'a,
51 B: 'a,
52 {
53 match self.as_ref() {
54 Ref::Value(value) => value.language(),
55 _ => None,
56 }
57 }
58
59 #[inline]
60 fn is_value(&self) -> bool {
62 matches!(self.as_ref(), Ref::Value(_))
63 }
64
65 #[inline]
66 fn is_node(&self) -> bool {
68 matches!(self.as_ref(), Ref::Node(_))
69 }
70
71 #[inline]
72 fn is_graph(&self) -> bool {
75 match self.as_ref() {
76 Ref::Node(n) => n.is_graph(),
77 _ => false,
78 }
79 }
80
81 #[inline]
82 fn is_list(&self) -> bool {
84 matches!(self.as_ref(), Ref::List(_))
85 }
86}
87
88pub enum Ref<'a, T, B> {
90 Value(&'a Value<T>),
92
93 Node(&'a Node<T, B>),
95
96 List(&'a List<T, B>),
98}
99
100pub type IndexedObject<T, B = ()> = Indexed<Object<T, B>>;
102
103#[allow(clippy::derived_hash_with_manual_eq)]
112#[derive(Educe, Debug, Clone, Hash)]
113#[educe(PartialEq(bound(T: Eq + Hash, B: Eq + Hash)))]
114pub enum Object<T = IriBuf, B = BlankIdBuf> {
115 Value(Value<T>),
117
118 Node(Box<Node<T, B>>),
120
121 List(List<T, B>),
123}
124
125impl<T: Eq + Hash, B: Eq + Hash> Eq for Object<T, B> {}
126
127impl<T, B> Object<T, B> {
128 #[inline(always)]
130 #[must_use]
131 pub fn null() -> Self {
132 Self::Value(Value::null())
133 }
134
135 #[inline(always)]
137 pub fn node(n: Node<T, B>) -> Self {
138 Self::Node(Box::new(n))
139 }
140
141 #[inline(always)]
143 pub fn id(&self) -> Option<&Id<T, B>> {
144 match self {
145 Object::Node(n) => n.id.as_ref(),
146 _ => None,
147 }
148 }
149
150 pub fn identify_all_with<V: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
156 &mut self,
157 vocabulary: &mut V,
158 generator: &mut G,
159 ) -> Result<(), crate::id::GeneratedIdError>
160 where
161 T: Eq + Hash,
162 B: Eq + Hash,
163 {
164 match self {
165 Object::Node(n) => n.identify_all_with(vocabulary, generator)?,
166 Object::List(l) => {
167 for object in l {
168 object.identify_all_with(vocabulary, generator)?;
169 }
170 }
171 Object::Value(_) => (),
172 }
173 Ok(())
174 }
175
176 pub fn identify_all<G: LocalGenerator>(&mut self, generator: &mut G) -> Result<(), crate::id::GeneratedIdError>
183 where
184 T: Eq + Hash,
185 B: Eq + Hash,
186 (): Vocabulary<Iri = T, BlankId = B>,
187 {
188 self.identify_all_with(&mut (), generator)
189 }
190
191 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
194 match self {
195 Self::List(l) => l.canonicalize_with(buffer),
196 Self::Node(n) => n.canonicalize_with(buffer),
197 Self::Value(v) => v.canonicalize_with(buffer),
198 }
199 }
200
201 pub fn canonicalize(&mut self) {
203 let mut buffer = ryu_js::Buffer::new();
204 self.canonicalize_with(&mut buffer);
205 }
206
207 pub fn types(&self) -> Types<'_, T, B> {
209 match self {
210 Self::Value(value) => Types::Value(value.typ()),
211 Self::Node(node) => Types::Node(node.types().iter()),
212 Self::List(_) => Types::List,
213 }
214 }
215
216 #[inline(always)]
221 pub fn as_iri(&self) -> Option<&T> {
222 match self {
223 Object::Node(node) => node.as_iri(),
224 _ => None,
225 }
226 }
227
228 #[inline(always)]
230 pub fn is_value(&self) -> bool {
231 matches!(self, Object::Value(_))
232 }
233
234 #[inline(always)]
236 pub fn as_value(&self) -> Option<&Value<T>> {
237 match self {
238 Self::Value(v) => Some(v),
239 _ => None,
240 }
241 }
242
243 #[inline(always)]
245 pub fn as_value_mut(&mut self) -> Option<&mut Value<T>> {
246 match self {
247 Self::Value(v) => Some(v),
248 _ => None,
249 }
250 }
251
252 #[inline(always)]
254 pub fn into_value(self) -> Option<Value<T>> {
255 match self {
256 Self::Value(v) => Some(v),
257 _ => None,
258 }
259 }
260
261 #[inline(always)]
263 pub fn is_node(&self) -> bool {
264 matches!(self, Object::Node(_))
265 }
266
267 #[inline(always)]
269 pub fn as_node(&self) -> Option<&Node<T, B>> {
270 match self {
271 Self::Node(n) => Some(n),
272 _ => None,
273 }
274 }
275
276 #[inline(always)]
278 pub fn as_node_mut(&mut self) -> Option<&mut Node<T, B>> {
279 match self {
280 Self::Node(n) => Some(n),
281 _ => None,
282 }
283 }
284
285 #[inline(always)]
287 pub fn into_node(self) -> Option<Node<T, B>> {
288 match self {
289 Self::Node(n) => Some(*n),
290 _ => None,
291 }
292 }
293
294 #[inline(always)]
296 pub fn is_graph(&self) -> bool {
297 match self {
298 Object::Node(n) => n.is_graph(),
299 _ => false,
300 }
301 }
302
303 #[inline(always)]
305 pub fn is_list(&self) -> bool {
306 matches!(self, Object::List(_))
307 }
308
309 #[inline(always)]
311 pub fn as_list(&self) -> Option<&List<T, B>> {
312 match self {
313 Self::List(l) => Some(l),
314 _ => None,
315 }
316 }
317
318 #[inline(always)]
320 pub fn as_list_mut(&mut self) -> Option<&mut List<T, B>> {
321 match self {
322 Self::List(l) => Some(l),
323 _ => None,
324 }
325 }
326
327 #[inline(always)]
329 pub fn into_list(self) -> Option<List<T, B>> {
330 match self {
331 Self::List(l) => Some(l),
332 _ => None,
333 }
334 }
335
336 #[inline(always)]
342 pub fn as_str(&self) -> Option<&str>
343 where
344 T: AsRef<str>,
345 B: AsRef<str>,
346 {
347 match self {
348 Object::Value(value) => value.as_str(),
349 Object::Node(node) => node.as_str(),
350 Object::List(_) => None,
351 }
352 }
353
354 #[inline(always)]
356 pub fn as_bool(&self) -> Option<bool> {
357 match self {
358 Object::Value(value) => value.as_bool(),
359 _ => None,
360 }
361 }
362
363 #[inline(always)]
365 pub fn as_number(&self) -> Option<&Number> {
366 match self {
367 Object::Value(value) => value.as_number(),
368 _ => None,
369 }
370 }
371
372 #[inline(always)]
375 pub fn language(&self) -> Option<&LenientLangTag> {
376 match self {
377 Object::Value(value) => value.language(),
378 _ => None,
379 }
380 }
381
382 pub fn traverse(&self) -> Traverse<'_, T, B> {
391 Traverse::new(Some(FragmentRef::Object(self)))
392 }
393
394 fn sub_fragments(&self) -> ObjectSubFragments<'_, T, B> {
395 match self {
396 Self::Value(v) => ObjectSubFragments::Value(v.entries()),
397 Self::List(l) => ObjectSubFragments::List(Some(l.entry())),
398 Self::Node(n) => ObjectSubFragments::Node(n.entries()),
399 }
400 }
401
402 pub fn equivalent(&self, other: &Self) -> bool
408 where
409 T: Eq + Hash,
410 B: Eq + Hash,
411 {
412 match (self, other) {
413 (Self::Value(a), Self::Value(b)) => a == b,
414 (Self::Node(a), Self::Node(b)) => a.equivalent(b),
415 _ => false,
416 }
417 }
418
419 pub fn entries(&self) -> Entries<'_, T, B> {
422 match self {
423 Self::Value(value) => Entries::Value(value.entries()),
424 Self::List(list) => Entries::List(Some(list.entry())),
425 Self::Node(node) => Entries::Node(node.entries()),
426 }
427 }
428
429 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>
432 where
433 U: Eq + Hash,
434 C: Eq + Hash,
435 {
436 self.map_ids_with(&mut map_iri, &mut map_id)
437 }
438
439 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>
440 where
441 U: Eq + Hash,
442 C: Eq + Hash,
443 {
444 match self {
445 Self::Value(value) => Object::Value(value.map_ids(map_iri)),
446 Self::List(list) => Object::List(list.map_ids_with(map_iri, map_id)),
447 Self::Node(node) => Object::Node(Box::new((*node).map_ids_with(map_iri, map_id))),
448 }
449 }
450}
451
452impl<T, B> Relabel<T, B> for Object<T, B> {
453 fn relabel_with<N: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
454 &mut self,
455 vocabulary: &mut N,
456 generator: &mut G,
457 relabeling: &mut HashMap<B, ValidId<T, B>>,
458 ) -> Result<(), crate::id::GeneratedIdError>
459 where
460 T: Clone + Eq + Hash,
461 B: Clone + Eq + Hash,
462 {
463 match self {
464 Self::Node(n) => n.relabel_with(vocabulary, generator, relabeling),
465 Self::List(l) => l.relabel_with(vocabulary, generator, relabeling),
466 Self::Value(_) => Ok(()),
467 }
468 }
469}
470
471impl<T: Eq + Hash, B: Eq + Hash> Indexed<Object<T, B>> {
472 pub fn equivalent(&self, other: &Self) -> bool {
475 self.index() == other.index() && self.inner().equivalent(other.inner())
476 }
477}
478
479impl<T, B> Indexed<Object<T, B>> {
480 #[inline(always)]
482 pub fn into_indexed_node(self) -> Option<Indexed<Node<T, B>>> {
483 let (object, index) = self.into_parts();
484 object.into_node().map(|node| Indexed::new(node, index))
485 }
486
487 #[inline(always)]
489 pub fn into_indexed_value(self) -> Option<Indexed<Value<T>>> {
490 let (object, index) = self.into_parts();
491 object.into_value().map(|value| Indexed::new(value, index))
492 }
493
494 #[inline(always)]
496 pub fn into_indexed_list(self) -> Option<Indexed<List<T, B>>> {
497 let (object, index) = self.into_parts();
498 object.into_list().map(|list| Indexed::new(list, index))
499 }
500
501 pub fn into_unnamed_graph(self) -> Result<Graph<T, B>, Self> {
507 let (obj, index) = self.into_parts();
508 match obj {
509 Object::Node(n) => match n.into_unnamed_graph() {
510 Ok(g) => Ok(g),
511 Err(n) => Err(Indexed::new(Object::Node(n), index)),
512 },
513 obj => Err(Indexed::new(obj, index)),
514 }
515 }
516
517 pub fn entries(&self) -> IndexedEntries<'_, T, B> {
520 IndexedEntries {
521 index: self.index(),
522 inner: self.inner().entries(),
523 }
524 }
525}
526
527#[derive(Educe)]
528#[educe(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(Educe)]
564#[educe(Clone)]
565pub struct IndexedEntries<'a, T, B> {
567 index: Option<&'a str>,
568 inner: Entries<'a, T, B>,
569}
570
571impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
572 type Item = IndexedEntryRef<'a, T, B>;
573
574 fn size_hint(&self) -> (usize, Option<usize>) {
575 let len = self.inner.len() + usize::from(self.index.is_some());
576 (len, Some(len))
577 }
578
579 fn next(&mut self) -> Option<Self::Item> {
580 self.index
581 .take()
582 .map(IndexedEntryRef::Index)
583 .or_else(|| self.inner.next().map(IndexedEntryRef::Object))
584 }
585}
586
587impl<T, B> ExactSizeIterator for IndexedEntries<'_, T, B> {}
588
589#[derive(Educe, PartialEq, Eq)]
595#[educe(Clone(bound(false)), Copy(bound(false)))]
596pub enum EntryKeyRef<'a, T, B> {
598 Value(value::EntryKey),
600 List,
602 Node(node::EntryKeyRef<'a, T, B>),
604}
605
606impl<'a, T, B> EntryKeyRef<'a, T, B> {
607 #[must_use]
609 pub fn into_keyword(self) -> Option<Keyword> {
610 match self {
611 Self::Value(e) => Some(e.into_keyword()),
612 Self::List => Some(Keyword::List),
613 Self::Node(e) => e.into_keyword(),
614 }
615 }
616
617 #[must_use]
619 pub fn as_keyword(&self) -> Option<Keyword> {
620 self.into_keyword()
621 }
622
623 #[must_use]
625 pub fn into_str(self) -> &'a str
626 where
627 T: AsRef<str>,
628 B: AsRef<str>,
629 {
630 match self {
631 Self::Value(e) => e.into_str(),
632 Self::List => "@list",
633 Self::Node(e) => e.into_str(),
634 }
635 }
636
637 #[must_use]
639 pub fn as_str(self) -> &'a str
640 where
641 T: AsRef<str>,
642 B: AsRef<str>,
643 {
644 self.into_str()
645 }
646}
647
648impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for EntryKeyRef<'a, T, B> {
649 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
650 match self {
651 EntryKeyRef::Value(e) => e.into_str(),
652 EntryKeyRef::List => "@list",
653 EntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
654 }
655 }
656}
657
658#[derive(Educe)]
659#[educe(Clone(bound(false)), Copy(bound(false)))]
660pub enum EntryValueRef<'a, T, B> {
662 Value(value::EntryRef<'a, T>),
664 List(&'a [IndexedObject<T, B>]),
666 Node(node::EntryValueRef<'a, T, B>),
668}
669
670#[derive(Educe)]
671#[educe(Clone(bound(false)), Copy(bound(false)))]
672pub enum EntryRef<'a, T, B> {
674 Value(value::EntryRef<'a, T>),
676 List(&'a [IndexedObject<T, B>]),
678 Node(node::EntryRef<'a, T, B>),
680}
681
682impl<'a, T, B> EntryRef<'a, T, B> {
683 #[must_use]
685 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
686 match self {
687 Self::Value(e) => EntryKeyRef::Value(e.key()),
688 Self::List(_) => EntryKeyRef::List,
689 Self::Node(e) => EntryKeyRef::Node(e.key()),
690 }
691 }
692
693 #[must_use]
695 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
696 self.into_key()
697 }
698
699 #[must_use]
701 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
702 match self {
703 Self::Value(v) => EntryValueRef::Value(v),
704 Self::List(v) => EntryValueRef::List(v),
705 Self::Node(e) => EntryValueRef::Node(e.value()),
706 }
707 }
708
709 #[must_use]
711 pub fn value(&self) -> EntryValueRef<'a, T, B> {
712 self.into_value()
713 }
714
715 #[must_use]
717 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
718 match self {
719 Self::Value(e) => (EntryKeyRef::Value(e.key()), EntryValueRef::Value(e)),
720 Self::List(e) => (EntryKeyRef::List, EntryValueRef::List(e)),
721 Self::Node(e) => {
722 let (k, v) = e.into_key_value();
723 (EntryKeyRef::Node(k), EntryValueRef::Node(v))
724 }
725 }
726 }
727
728 #[must_use]
730 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
731 self.into_key_value()
732 }
733}
734
735#[derive(Educe, PartialEq, Eq)]
736#[educe(Clone(bound(false)), Copy(bound(false)))]
737pub enum IndexedEntryKeyRef<'a, T, B> {
739 Index,
741 Object(EntryKeyRef<'a, T, B>),
743}
744
745impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
746 #[must_use]
748 pub fn into_keyword(self) -> Option<Keyword> {
749 match self {
750 Self::Index => Some(Keyword::Index),
751 Self::Object(e) => e.into_keyword(),
752 }
753 }
754
755 #[must_use]
757 pub fn as_keyword(&self) -> Option<Keyword> {
758 self.into_keyword()
759 }
760
761 #[must_use]
763 pub fn into_str(self) -> &'a str
764 where
765 T: AsRef<str>,
766 B: AsRef<str>,
767 {
768 match self {
769 Self::Index => "@index",
770 Self::Object(e) => e.into_str(),
771 }
772 }
773
774 #[must_use]
776 pub fn as_str(&self) -> &'a str
777 where
778 T: AsRef<str>,
779 B: AsRef<str>,
780 {
781 self.into_str()
782 }
783}
784
785impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for IndexedEntryKeyRef<'a, T, B> {
786 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
787 match self {
788 IndexedEntryKeyRef::Index => "@index",
789 IndexedEntryKeyRef::Object(e) => e.into_with(vocabulary).into_str(),
790 }
791 }
792}
793
794#[derive(Educe)]
795#[educe(Clone(bound(false)), Copy(bound(false)))]
796pub enum IndexedEntryValueRef<'a, T, B> {
798 Index(&'a str),
800 Object(EntryValueRef<'a, T, B>),
802}
803
804#[derive(Educe)]
805#[educe(Clone(bound(false)), Copy(bound(false)))]
806pub enum IndexedEntryRef<'a, T, B> {
808 Index(&'a str),
810 Object(EntryRef<'a, T, B>),
812}
813
814impl<'a, T, B> IndexedEntryRef<'a, T, B> {
815 #[must_use]
817 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
818 match self {
819 Self::Index(_) => IndexedEntryKeyRef::Index,
820 Self::Object(e) => IndexedEntryKeyRef::Object(e.key()),
821 }
822 }
823
824 #[must_use]
826 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
827 self.into_key()
828 }
829
830 #[must_use]
832 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
833 match self {
834 Self::Index(v) => IndexedEntryValueRef::Index(v),
835 Self::Object(e) => IndexedEntryValueRef::Object(e.value()),
836 }
837 }
838
839 #[must_use]
841 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
842 self.into_value()
843 }
844
845 #[must_use]
847 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
848 match self {
849 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
850 Self::Object(e) => {
851 let (k, v) = e.into_key_value();
852 (IndexedEntryKeyRef::Object(k), IndexedEntryValueRef::Object(v))
853 }
854 }
855 }
856
857 #[must_use]
859 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
860 self.into_key_value()
861 }
862}
863
864pub trait TryFromJson<T, B>: Sized {
869 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson>;
876}
877
878pub trait TryFromJsonObject<T, B>: Sized {
883 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, object: jstrict::Object) -> Result<Self, InvalidExpandedJson>;
890}
891
892impl<T, B, V: TryFromJson<T, B>> TryFromJson<T, B> for Vec<V> {
893 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
894 match value {
895 jstrict::Value::Array(items) => {
896 let mut result = Vec::new();
897
898 for item in items {
899 result.push(V::try_from_json_in(vocabulary, item)?);
900 }
901
902 Ok(result)
903 }
904 _ => Err(InvalidExpandedJson::InvalidList),
905 }
906 }
907}
908
909impl<T, B, V: Eq + Hash + TryFromJson<T, B>> TryFromJson<T, B> for IndexSet<V> {
910 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
911 match value {
912 jstrict::Value::Array(items) => {
913 let mut result = IndexSet::default();
914
915 for item in items {
916 result.insert(V::try_from_json_in(vocabulary, item)?);
917 }
918
919 Ok(result)
920 }
921 _ => Err(InvalidExpandedJson::InvalidList),
922 }
923 }
924}
925
926impl<T: Eq + Hash, B: Eq + Hash> TryFromJson<T, B> for Object<T, B> {
927 fn try_from_json_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, value: jstrict::Value) -> Result<Self, InvalidExpandedJson> {
928 match value {
929 jstrict::Value::Object(object) => Self::try_from_json_object_in(vocabulary, object),
930 _ => Err(InvalidExpandedJson::InvalidObject),
931 }
932 }
933}
934
935impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Object<T, B> {
936 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, mut object: jstrict::Object) -> Result<Self, InvalidExpandedJson> {
937 match object.remove_unique("@context").map_err(InvalidExpandedJson::duplicate_key)? {
938 Some(_) => Err(InvalidExpandedJson::NotExpanded),
939 None => {
940 if let Some(value_entry) = object.remove_unique("@value").map_err(InvalidExpandedJson::duplicate_key)? {
941 Ok(Self::Value(Value::try_from_json_object_in(vocabulary, object, value_entry)?))
942 } else if let Some(list_entry) = object.remove_unique("@list").map_err(InvalidExpandedJson::duplicate_key)? {
943 Ok(Self::List(List::try_from_json_object_in(vocabulary, object, list_entry)?))
944 } else {
945 let node = Node::try_from_json_object_in(vocabulary, object)?;
946 Ok(Self::node(node))
947 }
948 }
949 }
950 }
951}
952
953#[derive(Debug, thiserror::Error)]
958pub enum InvalidExpandedJson {
959 #[error("invalid object")]
961 InvalidObject,
962 #[error("invalid `@list` value")]
964 InvalidList,
965 #[error("invalid `@index` value")]
967 InvalidIndex,
968 #[error("invalid `@id` value")]
970 InvalidId,
971 #[error("invalid `@type` value")]
973 InvalidValueType,
974 #[error("invalid literal")]
976 InvalidLiteral,
977 #[error("invalid `@language` value")]
979 InvalidLanguage,
980 #[error("invalid `@direction` value")]
982 InvalidDirection,
983 #[error("invalid language-tagged string")]
985 InvalidLangString,
986 #[error("not an expanded document")]
988 NotExpanded,
989 #[error("unexpected entry")]
991 UnexpectedEntry,
992 #[error("duplicate key `{0}`")]
994 DuplicateKey(jstrict::object::Key),
995 #[error("unexpected {0}, expected {1}")]
997 Unexpected(jstrict::Kind, jstrict::Kind),
998}
999
1000impl InvalidExpandedJson {
1001 #[must_use]
1003 pub fn duplicate_key(jstrict::object::Duplicate(a, _): jstrict::object::Duplicate<jstrict::object::Entry>) -> Self {
1004 InvalidExpandedJson::DuplicateKey(a.key)
1005 }
1006}
1007
1008impl<T, B> Any<T, B> for Object<T, B> {
1009 #[inline(always)]
1010 fn as_ref(&self) -> Ref<'_, T, B> {
1011 match self {
1012 Object::Value(value) => Ref::Value(value),
1013 Object::Node(node) => Ref::Node(node),
1014 Object::List(list) => Ref::List(list),
1015 }
1016 }
1017}
1018
1019impl<T, B> From<Value<T>> for Object<T, B> {
1020 #[inline(always)]
1021 fn from(value: Value<T>) -> Self {
1022 Self::Value(value)
1023 }
1024}
1025
1026impl<T, B> From<Node<T, B>> for Object<T, B> {
1027 #[inline(always)]
1028 fn from(node: Node<T, B>) -> Self {
1029 Self::node(node)
1030 }
1031}
1032
1033pub enum Types<'a, T, B> {
1035 Value(Option<value::TypeRef<'a, T>>),
1037 Node(std::slice::Iter<'a, Id<T, B>>),
1039 List,
1041}
1042
1043impl<'a, T, B> Iterator for Types<'a, T, B> {
1044 type Item = TypeRef<'a, T, B>;
1045
1046 fn next(&mut self) -> Option<Self::Item> {
1047 match self {
1048 Self::Value(ty) => ty.take().map(TypeRef::from_value_type),
1049 Self::Node(tys) => tys.next().map(TypeRef::from_reference),
1050 Self::List => None,
1051 }
1052 }
1053}
1054
1055pub struct Objects<'a, T, B>(Option<std::slice::Iter<'a, IndexedObject<T, B>>>);
1057
1058impl<'a, T, B> Objects<'a, T, B> {
1059 #[inline(always)]
1060 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedObject<T, B>>>) -> Self {
1061 Self(inner)
1062 }
1063}
1064
1065impl<'a, T, B> Iterator for Objects<'a, T, B> {
1066 type Item = &'a IndexedObject<T, B>;
1067
1068 #[inline(always)]
1069 fn next(&mut self) -> Option<&'a IndexedObject<T, B>> {
1070 match &mut self.0 {
1071 None => None,
1072 Some(it) => it.next(),
1073 }
1074 }
1075}
1076
1077pub enum FragmentRef<'a, T, B> {
1079 IndexEntry(&'a str),
1081
1082 IndexKey,
1084
1085 IndexValue(&'a str),
1087
1088 Object(&'a Object<T, B>),
1090
1091 IndexedObject(&'a Indexed<Object<T, B>>),
1093
1094 Node(&'a Node<T, B>),
1096
1097 IndexedNode(&'a IndexedNode<T, B>),
1099
1100 IndexedNodeList(&'a [IndexedNode<T, B>]),
1102
1103 ValueFragment(value::FragmentRef<'a, T>),
1105
1106 ListFragment(list::FragmentRef<'a, T, B>),
1108
1109 NodeFragment(node::FragmentRef<'a, T, B>),
1111}
1112
1113impl<'a, T, B> FragmentRef<'a, T, B> {
1114 #[must_use]
1116 pub fn into_ref(self) -> Option<Ref<'a, T, B>> {
1117 match self {
1118 Self::Object(o) => Some(o.as_ref()),
1119 Self::IndexedObject(o) => Some(o.inner().as_ref()),
1120 Self::Node(n) => Some(n.as_ref()),
1121 Self::IndexedNode(n) => Some(n.inner().as_ref()),
1122 _ => None,
1123 }
1124 }
1125
1126 pub fn into_id(self) -> Option<Id<&'a T, &'a B>> {
1128 match self {
1129 Self::ValueFragment(i) => i.into_iri().map(Id::iri),
1130 Self::NodeFragment(i) => i.into_id().map(Into::into),
1131 _ => None,
1132 }
1133 }
1134
1135 pub fn as_id(&self) -> Option<Id<&'a T, &'a B>> {
1137 match self {
1138 Self::ValueFragment(i) => i.as_iri().map(Id::iri),
1139 Self::NodeFragment(i) => i.as_id().map(Into::into),
1140 _ => None,
1141 }
1142 }
1143
1144 #[must_use]
1146 pub fn is_json_array(&self) -> bool {
1147 match self {
1148 Self::IndexedNodeList(_) => true,
1149 Self::ValueFragment(i) => i.is_json_array(),
1150 Self::NodeFragment(n) => n.is_json_array(),
1151 _ => false,
1152 }
1153 }
1154
1155 #[must_use]
1157 pub fn is_json_object(&self) -> bool {
1158 match self {
1159 Self::Object(_) | Self::IndexedObject(_) | Self::Node(_) | Self::IndexedNode(_) => true,
1160 Self::ValueFragment(i) => i.is_json_object(),
1161 Self::NodeFragment(i) => i.is_json_object(),
1162 _ => false,
1163 }
1164 }
1165
1166 #[must_use]
1168 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1169 match self {
1170 Self::IndexEntry(v) => SubFragments::IndexEntry(Some(()), Some(v)),
1171 Self::Object(o) => SubFragments::Object(None, o.sub_fragments()),
1172 Self::IndexedObject(o) => SubFragments::Object(o.index(), o.sub_fragments()),
1173 Self::Node(n) => SubFragments::Object(None, ObjectSubFragments::Node(n.entries())),
1174 Self::IndexedNode(n) => SubFragments::Object(n.index(), ObjectSubFragments::Node(n.inner().entries())),
1175 Self::IndexedNodeList(l) => SubFragments::IndexedNodeList(l.iter()),
1176 Self::ValueFragment(i) => SubFragments::Value(i.sub_fragments()),
1177 Self::NodeFragment(i) => SubFragments::Node(i.sub_fragments()),
1178 Self::ListFragment(l) => SubFragments::List(l.sub_fragments()),
1179 Self::IndexKey | Self::IndexValue(_) => SubFragments::None,
1180 }
1181 }
1182}
1183
1184pub enum ObjectSubFragments<'a, T, B> {
1186 List(Option<&'a [IndexedObject<T, B>]>),
1188 Value(value::Entries<'a, T>),
1190 Node(node::Entries<'a, T, B>),
1192}
1193
1194impl<'a, T, B> Iterator for ObjectSubFragments<'a, T, B> {
1195 type Item = FragmentRef<'a, T, B>;
1196
1197 fn next(&mut self) -> Option<Self::Item> {
1198 match self {
1199 Self::List(l) => l.take().map(|e| FragmentRef::ListFragment(list::FragmentRef::Entry(e))),
1200 Self::Value(e) => e.next_back().map(|e| FragmentRef::ValueFragment(value::FragmentRef::Entry(e))),
1201 Self::Node(e) => e.next().map(|e| FragmentRef::NodeFragment(node::FragmentRef::Entry(e))),
1202 }
1203 }
1204}
1205
1206pub enum SubFragments<'a, T, B> {
1208 None,
1210 IndexEntry(Option<()>, Option<&'a str>),
1212 Object(Option<&'a str>, ObjectSubFragments<'a, T, B>),
1214 Value(value::SubFragments<'a, T>),
1216 Node(node::SubFragments<'a, T, B>),
1218 List(list::SubFragments<'a, T, B>),
1220 IndexedNodeList(std::slice::Iter<'a, IndexedNode<T, B>>),
1222}
1223
1224impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1225 type Item = FragmentRef<'a, T, B>;
1226
1227 fn next(&mut self) -> Option<Self::Item> {
1228 match self {
1229 Self::None => None,
1230 Self::IndexEntry(k, v) => k.take().map(|()| FragmentRef::IndexKey).or_else(|| v.take().map(FragmentRef::IndexValue)),
1231 Self::Object(index, i) => match index.take() {
1232 Some(index) => Some(FragmentRef::IndexEntry(index)),
1233 None => i.next(),
1234 },
1235 Self::Value(i) => i.next().map(FragmentRef::ValueFragment),
1236 Self::Node(i) => i.next(),
1237 Self::List(i) => i.next(),
1238 Self::IndexedNodeList(i) => i.next().map(FragmentRef::IndexedNode),
1239 }
1240 }
1241}
1242
1243pub struct Traverse<'a, T, B> {
1245 stack: SmallVec<[FragmentRef<'a, T, B>; 8]>,
1246}
1247
1248impl<'a, T, B> Traverse<'a, T, B> {
1249 pub(crate) fn new(items: impl IntoIterator<Item = FragmentRef<'a, T, B>>) -> Self {
1250 let stack = items.into_iter().collect();
1251 Self { stack }
1252 }
1253}
1254
1255impl<'a, T, B> Iterator for Traverse<'a, T, B> {
1256 type Item = FragmentRef<'a, T, B>;
1257
1258 fn next(&mut self) -> Option<Self::Item> {
1259 match self.stack.pop() {
1260 Some(item) => {
1261 self.stack.extend(item.sub_fragments());
1262 Some(item)
1263 }
1264 None => None,
1265 }
1266 }
1267}
1268
1269impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Object<T, B> {
1270 fn into_json_with(self, vocabulary: &N) -> jstrict::Value {
1271 match self {
1272 Self::Value(v) => v.into_json_with(vocabulary),
1273 Self::Node(n) => n.into_json_with(vocabulary),
1274 Self::List(l) => l.into_json_with(vocabulary),
1275 }
1276 }
1277}