1use super::{InvalidExpandedJson, Traverse, TryFromJson, TryFromJsonObject};
2use crate::{object, utils, Id, Indexed, IndexedObject, Object, Objects, Relabel, Term};
3use contextual::{IntoRefWithContext, WithContext};
4use educe::Educe;
5use indexmap::IndexSet;
6use iref::IriBuf;
7use json_ld_syntax::{IntoJson, IntoJsonWithContext, Keyword};
8use rdf_types::{BlankIdBuf, Generator, Subject, Vocabulary, VocabularyMut};
9use std::convert::TryFrom;
10use std::hash::{Hash, Hasher};
11
12pub mod multiset;
13pub mod properties;
14pub mod reverse_properties;
15
16pub use multiset::Multiset;
17pub use properties::Properties;
18pub use reverse_properties::ReverseProperties;
19
20pub type Graph<T, B> = IndexSet<IndexedObject<T, B>>;
21
22pub type Included<T, B> = IndexSet<IndexedNode<T, B>>;
23
24pub type IndexedNode<T = IriBuf, B = BlankIdBuf> = Indexed<Node<T, B>>;
25
26#[derive(Educe, Debug, Clone)]
35#[educe(Eq(bound = "T: Eq + Hash, B: Eq + Hash"))]
36pub struct Node<T = IriBuf, B = BlankIdBuf> {
37 pub id: Option<Id<T, B>>,
41
42 pub types: Option<Vec<Id<T, B>>>,
46
47 pub graph: Option<Graph<T, B>>,
51
52 pub included: Option<Included<T, B>>,
56
57 pub properties: Properties<T, B>,
61
62 pub reverse_properties: Option<ReverseProperties<T, B>>,
66}
67
68impl<T, B> Default for Node<T, B> {
69 #[inline(always)]
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl<T, B> Node<T, B> {
76 #[inline(always)]
78 pub fn new() -> Self {
79 Self {
80 id: None,
81 types: None,
82 graph: None,
83 included: None,
84 properties: Properties::new(),
85 reverse_properties: None,
86 }
87 }
88
89 #[inline(always)]
91 pub fn with_id(id: Id<T, B>) -> Self {
92 Self {
93 id: Some(id),
94 types: None,
95 graph: None,
96 included: None,
97 properties: Properties::new(),
98 reverse_properties: None,
99 }
100 }
101
102 pub fn new_graph(id: Id<T, B>, graph: Graph<T, B>) -> Self {
104 Self {
105 id: Some(id),
106 types: None,
107 graph: Some(graph),
108 included: None,
109 properties: Properties::new(),
110 reverse_properties: None,
111 }
112 }
113
114 #[inline(always)]
118 pub fn reverse_properties_mut_or_default(&mut self) -> &mut ReverseProperties<T, B> {
119 self.reverse_properties
120 .get_or_insert_with(ReverseProperties::default)
121 }
122
123 #[inline(always)]
127 pub fn included_mut_or_default(&mut self) -> &mut Included<T, B> {
128 self.included.get_or_insert_with(Included::default)
129 }
130
131 pub fn identify_all_with<V: Vocabulary<Iri = T, BlankId = B>, G: Generator<V>>(
134 &mut self,
135 vocabulary: &mut V,
136 generator: &mut G,
137 ) where
138 T: Eq + Hash,
139 B: Eq + Hash,
140 {
141 if self.id.is_none() {
142 self.id = Some(generator.next(vocabulary).into())
143 }
144
145 if let Some(graph) = self.graph_mut() {
146 *graph = std::mem::take(graph)
147 .into_iter()
148 .map(|mut o| {
149 o.identify_all_with(vocabulary, generator);
150 o
151 })
152 .collect();
153 }
154
155 if let Some(included) = self.included_mut() {
156 *included = std::mem::take(included)
157 .into_iter()
158 .map(|mut n| {
159 n.identify_all_with(vocabulary, generator);
160 n
161 })
162 .collect();
163 }
164
165 for (_, objects) in self.properties_mut() {
166 for object in objects {
167 object.identify_all_with(vocabulary, generator);
168 }
169 }
170
171 if let Some(reverse_properties) = self.reverse_properties_mut() {
172 for (_, nodes) in reverse_properties.iter_mut() {
173 for node in nodes {
174 node.identify_all_with(vocabulary, generator);
175 }
176 }
177 }
178 }
179
180 pub fn identify_all<G: Generator>(&mut self, generator: &mut G)
182 where
183 T: Eq + Hash,
184 B: Eq + Hash,
185 (): Vocabulary<Iri = T, BlankId = B>,
186 {
187 self.identify_all_with(&mut (), generator)
188 }
189
190 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
195 for (_, objects) in self.properties_mut() {
196 for object in objects {
197 object.canonicalize_with(buffer)
198 }
199 }
200
201 if let Some(reverse_properties) = self.reverse_properties_mut() {
202 for (_, nodes) in reverse_properties.iter_mut() {
203 for node in nodes {
204 node.canonicalize_with(buffer)
205 }
206 }
207 }
208 }
209
210 pub fn canonicalize(&mut self) {
212 let mut buffer = ryu_js::Buffer::new();
213 self.canonicalize_with(&mut buffer)
214 }
215
216 #[inline(always)]
220 pub fn as_iri(&self) -> Option<&T> {
221 if let Some(id) = &self.id {
222 id.as_iri()
223 } else {
224 None
225 }
226 }
227
228 #[inline(always)]
232 pub fn as_str(&self) -> Option<&str>
233 where
234 T: AsRef<str>,
235 {
236 match self.as_iri() {
237 Some(iri) => Some(iri.as_ref()),
238 None => None,
239 }
240 }
241
242 #[inline(always)]
244 pub fn types(&self) -> &[Id<T, B>] {
245 match self.types.as_ref() {
246 Some(entry) => entry,
247 None => &[],
248 }
249 }
250
251 #[inline(always)]
253 pub fn types_mut(&mut self) -> &mut [Id<T, B>] {
254 match self.types.as_mut() {
255 Some(entry) => entry,
256 None => &mut [],
257 }
258 }
259
260 pub fn types_mut_or_default(&mut self) -> &mut Vec<Id<T, B>> {
261 self.types.get_or_insert_with(Vec::new)
262 }
263
264 pub fn types_mut_or_insert(&mut self, value: Vec<Id<T, B>>) -> &mut Vec<Id<T, B>> {
265 self.types.get_or_insert(value)
266 }
267
268 pub fn types_mut_or_insert_with(
269 &mut self,
270 f: impl FnOnce() -> Vec<Id<T, B>>,
271 ) -> &mut Vec<Id<T, B>> {
272 self.types.get_or_insert_with(f)
273 }
274
275 #[inline]
277 pub fn has_type<U>(&self, ty: &U) -> bool
278 where
279 Id<T, B>: PartialEq<U>,
280 {
281 for self_ty in self.types() {
282 if self_ty == ty {
283 return true;
284 }
285 }
286
287 false
288 }
289
290 #[inline]
294 pub fn is_empty(&self) -> bool {
295 self.types.is_none()
296 && self.graph.is_none()
297 && self.included.is_none()
298 && self.properties.is_empty()
299 && self.reverse_properties.is_none()
300 }
301
302 #[inline]
306 pub fn is_graph(&self) -> bool {
307 self.graph.is_some()
308 && self.types.is_none()
309 && self.included.is_none()
310 && self.properties.is_empty()
311 && self.reverse_properties.is_none()
312 }
313
314 #[inline(always)]
316 pub fn is_simple_graph(&self) -> bool {
317 self.id.is_none() && self.is_graph()
318 }
319
320 #[inline(always)]
322 pub fn graph(&self) -> Option<&Graph<T, B>> {
323 self.graph.as_ref()
324 }
325
326 #[inline(always)]
328 pub fn graph_mut(&mut self) -> Option<&mut Graph<T, B>> {
329 self.graph.as_mut()
330 }
331
332 #[inline(always)]
334 pub fn graph_entry(&self) -> Option<&Graph<T, B>> {
335 self.graph.as_ref()
336 }
337
338 #[inline(always)]
340 pub fn graph_entry_mut(&mut self) -> Option<&mut Graph<T, B>> {
341 self.graph.as_mut()
342 }
343
344 #[inline(always)]
346 pub fn set_graph_entry(&mut self, graph: Option<Graph<T, B>>) {
347 self.graph = graph
348 }
349
350 #[inline(always)]
354 pub fn included_entry(&self) -> Option<&Included<T, B>> {
355 self.included.as_ref()
356 }
357
358 #[inline(always)]
362 pub fn included_entry_mut(&mut self) -> Option<&mut Included<T, B>> {
363 self.included.as_mut()
364 }
365
366 pub fn included(&self) -> Option<&Included<T, B>> {
368 self.included.as_ref()
369 }
370
371 pub fn included_mut(&mut self) -> Option<&mut Included<T, B>> {
373 self.included.as_mut()
374 }
375
376 #[inline(always)]
378 pub fn set_included(&mut self, included: Option<Included<T, B>>) {
379 self.included = included
380 }
381
382 #[inline(always)]
384 pub fn properties(&self) -> &Properties<T, B> {
385 &self.properties
386 }
387
388 #[inline(always)]
390 pub fn properties_mut(&mut self) -> &mut Properties<T, B> {
391 &mut self.properties
392 }
393
394 #[inline(always)]
396 pub fn reverse_properties(&self) -> Option<&ReverseProperties<T, B>> {
397 self.reverse_properties.as_ref()
398 }
399
400 #[inline(always)]
402 pub fn reverse_properties_entry(&self) -> Option<&ReverseProperties<T, B>> {
403 self.reverse_properties.as_ref()
404 }
405
406 #[inline(always)]
408 pub fn reverse_properties_mut(&mut self) -> Option<&mut ReverseProperties<T, B>> {
409 self.reverse_properties.as_mut()
410 }
411
412 pub fn set_reverse_properties(&mut self, reverse_properties: Option<ReverseProperties<T, B>>) {
413 self.reverse_properties = reverse_properties
414 }
415
416 #[inline]
421 pub fn is_unnamed_graph(&self) -> bool {
422 self.graph.is_some()
423 && self.id.is_none()
424 && self.types.is_none()
425 && self.included.is_none()
426 && self.properties.is_empty()
427 && self.reverse_properties.is_none()
428 }
429
430 #[allow(clippy::result_large_err)]
435 #[inline(always)]
436 pub fn into_unnamed_graph(self) -> Result<Graph<T, B>, Self> {
437 if self.is_unnamed_graph() {
438 Ok(self.graph.unwrap())
439 } else {
440 Err(self)
441 }
442 }
443
444 pub fn traverse(&self) -> Traverse<T, B> {
445 Traverse::new(Some(super::FragmentRef::Node(self)))
446 }
447
448 #[inline(always)]
449 pub fn count(&self, f: impl FnMut(&super::FragmentRef<T, B>) -> bool) -> usize {
450 self.traverse().filter(f).count()
451 }
452
453 pub fn entries(&self) -> Entries<T, B> {
454 Entries {
455 id: self.id.as_ref(),
456 type_: self.types.as_deref(),
457 graph: self.graph.as_ref(),
458 included: self.included.as_ref(),
459 reverse: self.reverse_properties.as_ref(),
460 properties: self.properties.iter(),
461 }
462 }
463
464 pub fn map_ids<U, C>(
466 self,
467 mut map_iri: impl FnMut(T) -> U,
468 mut map_id: impl FnMut(Id<T, B>) -> Id<U, C>,
469 ) -> Node<U, C>
470 where
471 U: Eq + Hash,
472 C: Eq + Hash,
473 {
474 self.map_ids_with(&mut map_iri, &mut map_id)
475 }
476
477 pub(crate) fn map_ids_with<U, C>(
478 self,
479 map_iri: &mut impl FnMut(T) -> U,
480 map_id: &mut impl FnMut(Id<T, B>) -> Id<U, C>,
481 ) -> Node<U, C>
482 where
483 U: Eq + Hash,
484 C: Eq + Hash,
485 {
486 Node {
487 id: self.id.map(&mut *map_id),
488 types: self
489 .types
490 .map(|t| t.into_iter().map(&mut *map_id).collect()),
491 graph: self.graph.map(|g| {
492 g.into_iter()
493 .map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id)))
494 .collect()
495 }),
496 included: self.included.map(|i| {
497 i.into_iter()
498 .map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id)))
499 .collect()
500 }),
501 properties: self
502 .properties
503 .into_iter()
504 .map(|(id, values)| {
505 (
506 map_id(id),
507 values
508 .into_iter()
509 .map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id)))
510 .collect::<Vec<_>>(),
511 )
512 })
513 .collect(),
514 reverse_properties: self.reverse_properties.map(|r| {
515 r.into_iter()
516 .map(|(id, values)| {
517 (
518 map_id(id),
519 values
520 .into_iter()
521 .map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id)))
522 .collect::<Vec<_>>(),
523 )
524 })
525 .collect()
526 }),
527 }
528 }
529}
530
531impl<T: Eq + Hash, B: Eq + Hash> Node<T, B> {
532 #[inline(always)]
546 pub fn has_key(&self, key: &Term<T, B>) -> bool {
547 match key {
548 Term::Keyword(Keyword::Id) => self.id.is_some(),
549 Term::Keyword(Keyword::Type) => self.types.is_some(),
550 Term::Keyword(Keyword::Graph) => self.graph.is_some(),
551 Term::Keyword(Keyword::Included) => self.included.is_some(),
552 Term::Keyword(Keyword::Reverse) => self.reverse_properties.is_some(),
553 Term::Id(prop) => self.properties.contains(prop),
554 _ => false,
555 }
556 }
557
558 #[inline(always)]
560 pub fn get<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(
561 &self,
562 prop: &Q,
563 ) -> Objects<T, B>
564 where
565 T: 'a,
566 {
567 self.properties.get(prop)
568 }
569
570 #[inline(always)]
575 pub fn get_any<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(
576 &self,
577 prop: &Q,
578 ) -> Option<&IndexedObject<T, B>>
579 where
580 T: 'a,
581 {
582 self.properties.get_any(prop)
583 }
584
585 #[inline(always)]
587 pub fn insert(&mut self, prop: Id<T, B>, value: IndexedObject<T, B>) {
588 self.properties.insert(prop, value)
589 }
590
591 #[inline(always)]
596 pub fn insert_all<Objects: Iterator<Item = IndexedObject<T, B>>>(
597 &mut self,
598 prop: Id<T, B>,
599 values: Objects,
600 ) {
601 self.properties.insert_all(prop, values)
602 }
603
604 pub fn reverse_properties_or_insert(
605 &mut self,
606 props: ReverseProperties<T, B>,
607 ) -> &mut ReverseProperties<T, B> {
608 self.reverse_properties.get_or_insert(props)
609 }
610
611 pub fn reverse_properties_or_default(&mut self) -> &mut ReverseProperties<T, B> {
612 self.reverse_properties
613 .get_or_insert_with(ReverseProperties::default)
614 }
615
616 pub fn reverse_properties_or_insert_with(
617 &mut self,
618 f: impl FnOnce() -> ReverseProperties<T, B>,
619 ) -> &mut ReverseProperties<T, B> {
620 self.reverse_properties.get_or_insert_with(f)
621 }
622
623 pub fn equivalent(&self, other: &Self) -> bool {
628 if self.id.is_some() && other.id.is_some() {
629 self == other
630 } else {
631 false
632 }
633 }
634}
635
636impl<T, B> Relabel<T, B> for Node<T, B> {
637 fn relabel_with<N: Vocabulary<Iri = T, BlankId = B>, G: Generator<N>>(
638 &mut self,
639 vocabulary: &mut N,
640 generator: &mut G,
641 relabeling: &mut hashbrown::HashMap<B, Subject<T, B>>,
642 ) where
643 T: Clone + Eq + Hash,
644 B: Clone + Eq + Hash,
645 {
646 self.id = match self.id.take() {
647 Some(Id::Valid(Subject::Blank(b))) => {
648 let value = relabeling
649 .entry(b)
650 .or_insert_with(|| generator.next(vocabulary))
651 .clone();
652 Some(value.into())
653 }
654 None => {
655 let value = generator.next(vocabulary);
656 Some(value.into())
657 }
658 id => id,
659 };
660
661 for ty in self.types_mut() {
662 if let Some(b) = ty.as_blank().cloned() {
663 *ty = relabeling
664 .entry(b)
665 .or_insert_with(|| generator.next(vocabulary))
666 .clone()
667 .into();
668 }
669 }
670
671 if let Some(graph) = self.graph_mut() {
672 *graph = std::mem::take(graph)
673 .into_iter()
674 .map(|mut o| {
675 o.relabel_with(vocabulary, generator, relabeling);
676 o
677 })
678 .collect();
679 }
680
681 if let Some(included) = self.included_mut() {
682 *included = std::mem::take(included)
683 .into_iter()
684 .map(|mut n| {
685 n.relabel_with(vocabulary, generator, relabeling);
686 n
687 })
688 .collect();
689 }
690
691 for (_, objects) in self.properties_mut() {
692 for object in objects {
693 object.relabel_with(vocabulary, generator, relabeling);
694 }
695 }
696
697 if let Some(reverse_properties) = self.reverse_properties_mut() {
698 for (_, nodes) in reverse_properties.iter_mut() {
699 for node in nodes {
700 node.relabel_with(vocabulary, generator, relabeling);
701 }
702 }
703 }
704 }
705}
706
707impl<T: Eq + Hash, B: Eq + Hash> PartialEq for Node<T, B> {
708 fn eq(&self, other: &Self) -> bool {
709 self.id.eq(&other.id)
710 && multiset::compare_unordered_opt(self.types.as_deref(), other.types.as_deref())
711 && self.graph.as_ref() == other.graph.as_ref()
712 && self.included.as_ref() == other.included.as_ref()
713 && self.properties.eq(&other.properties)
714 && self.reverse_properties.eq(&other.reverse_properties)
715 }
716}
717
718impl<T, B> Indexed<Node<T, B>> {
719 pub fn entries(&self) -> IndexedEntries<T, B> {
720 IndexedEntries {
721 index: self.index(),
722 inner: self.inner().entries(),
723 }
724 }
725}
726
727impl<T: Eq + Hash, B: Eq + Hash> Indexed<Node<T, B>> {
728 pub fn equivalent(&self, other: &Self) -> bool {
729 self.index() == other.index() && self.inner().equivalent(other.inner())
730 }
731}
732
733#[derive(Educe, PartialEq, Eq)]
734#[educe(Clone, Copy)]
735pub enum EntryKeyRef<'a, T, B> {
736 Id,
737 Type,
738 Graph,
739 Included,
740 Reverse,
741 Property(&'a Id<T, B>),
742}
743
744impl<'a, T, B> EntryKeyRef<'a, T, B> {
745 pub fn into_keyword(self) -> Option<Keyword> {
746 match self {
747 Self::Id => Some(Keyword::Id),
748 Self::Type => Some(Keyword::Type),
749 Self::Graph => Some(Keyword::Graph),
750 Self::Included => Some(Keyword::Included),
751 Self::Reverse => Some(Keyword::Reverse),
752 Self::Property(_) => None,
753 }
754 }
755
756 pub fn as_keyword(&self) -> Option<Keyword> {
757 self.into_keyword()
758 }
759
760 pub fn into_str(self) -> &'a str
761 where
762 T: AsRef<str>,
763 B: AsRef<str>,
764 {
765 match self {
766 Self::Id => "@id",
767 Self::Type => "@type",
768 Self::Graph => "@graph",
769 Self::Included => "@included",
770 Self::Reverse => "@reverse",
771 Self::Property(p) => p.as_str(),
772 }
773 }
774
775 pub fn as_str(&self) -> &'a str
776 where
777 T: AsRef<str>,
778 B: AsRef<str>,
779 {
780 self.into_str()
781 }
782}
783
784impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N>
785 for EntryKeyRef<'a, T, B>
786{
787 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
788 match self {
789 EntryKeyRef::Id => "@id",
790 EntryKeyRef::Type => "@type",
791 EntryKeyRef::Graph => "@graph",
792 EntryKeyRef::Included => "@included",
793 EntryKeyRef::Reverse => "@reverse",
794 EntryKeyRef::Property(p) => p.with(vocabulary).as_str(),
795 }
796 }
797}
798
799#[derive(Educe)]
800#[educe(Clone, Copy)]
801pub enum EntryValueRef<'a, T, B> {
802 Id(&'a Id<T, B>),
803 Type(&'a [Id<T, B>]),
804 Graph(&'a IndexSet<IndexedObject<T, B>>),
805 Included(&'a IndexSet<IndexedNode<T, B>>),
806 Reverse(&'a ReverseProperties<T, B>),
807 Property(&'a [IndexedObject<T, B>]),
808}
809
810impl<'a, T, B> EntryValueRef<'a, T, B> {
811 pub fn is_json_array(&self) -> bool {
812 matches!(
813 self,
814 Self::Type(_) | Self::Graph(_) | Self::Included(_) | Self::Property(_)
815 )
816 }
817
818 pub fn is_json_object(&self) -> bool {
819 matches!(self, Self::Reverse(_))
820 }
821
822 fn sub_fragments(&self) -> SubFragments<'a, T, B> {
823 match self {
824 Self::Type(l) => SubFragments::Type(l.iter()),
825 Self::Graph(g) => SubFragments::Graph(g.iter()),
826 Self::Included(i) => SubFragments::Included(i.iter()),
827 Self::Reverse(r) => SubFragments::Reverse(r.iter()),
828 Self::Property(p) => SubFragments::Property(p.iter()),
829 _ => SubFragments::None,
830 }
831 }
832}
833
834#[derive(Educe)]
835#[educe(Clone, Copy)]
836pub enum EntryRef<'a, T, B> {
837 Id(&'a Id<T, B>),
838 Type(&'a [Id<T, B>]),
839 Graph(&'a Graph<T, B>),
840 Included(&'a Included<T, B>),
841 Reverse(&'a ReverseProperties<T, B>),
842 Property(&'a Id<T, B>, &'a [IndexedObject<T, B>]),
843}
844
845impl<'a, T, B> EntryRef<'a, T, B> {
846 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
847 match self {
848 Self::Id(_) => EntryKeyRef::Id,
849 Self::Type(_) => EntryKeyRef::Type,
850 Self::Graph(_) => EntryKeyRef::Graph,
851 Self::Included(_) => EntryKeyRef::Included,
852 Self::Reverse(_) => EntryKeyRef::Reverse,
853 Self::Property(k, _) => EntryKeyRef::Property(k),
854 }
855 }
856
857 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
858 self.into_key()
859 }
860
861 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
862 match self {
863 Self::Id(v) => EntryValueRef::Id(v),
864 Self::Type(v) => EntryValueRef::Type(v),
865 Self::Graph(v) => EntryValueRef::Graph(v),
866 Self::Included(v) => EntryValueRef::Included(v),
867 Self::Reverse(v) => EntryValueRef::Reverse(v),
868 Self::Property(_, v) => EntryValueRef::Property(v),
869 }
870 }
871
872 pub fn value(&self) -> EntryValueRef<'a, T, B> {
873 self.into_value()
874 }
875
876 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
877 match self {
878 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(v)),
879 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
880 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(v)),
881 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(v)),
882 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(v)),
883 Self::Property(k, v) => (EntryKeyRef::Property(k), EntryValueRef::Property(v)),
884 }
885 }
886
887 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
888 match self {
889 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(*v)),
890 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
891 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(*v)),
892 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(*v)),
893 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(*v)),
894 Self::Property(k, v) => (EntryKeyRef::Property(*k), EntryValueRef::Property(v)),
895 }
896 }
897}
898
899#[derive(Educe)]
900#[educe(Clone)]
901pub struct Entries<'a, T, B> {
902 id: Option<&'a Id<T, B>>,
903 type_: Option<&'a [Id<T, B>]>,
904 graph: Option<&'a Graph<T, B>>,
905 included: Option<&'a Included<T, B>>,
906 reverse: Option<&'a ReverseProperties<T, B>>,
907 properties: properties::Iter<'a, T, B>,
908}
909
910impl<'a, T, B> Iterator for Entries<'a, T, B> {
911 type Item = EntryRef<'a, T, B>;
912
913 fn size_hint(&self) -> (usize, Option<usize>) {
914 let mut len = self.properties.len();
915
916 if self.id.is_some() {
917 len += 1
918 }
919
920 if self.type_.is_some() {
921 len += 1
922 }
923
924 if self.graph.is_some() {
925 len += 1
926 }
927
928 if self.included.is_some() {
929 len += 1
930 }
931
932 if self.reverse.is_some() {
933 len += 1
934 }
935
936 (len, Some(len))
937 }
938
939 fn next(&mut self) -> Option<Self::Item> {
940 self.id.take().map(EntryRef::Id).or_else(|| {
941 self.type_.take().map(EntryRef::Type).or_else(|| {
942 self.graph.take().map(EntryRef::Graph).or_else(|| {
943 self.included.take().map(EntryRef::Included).or_else(|| {
944 self.reverse.take().map(EntryRef::Reverse).or_else(|| {
945 self.properties
946 .next()
947 .map(|(k, v)| EntryRef::Property(k, v))
948 })
949 })
950 })
951 })
952 })
953 }
954}
955
956impl<'a, T, B> ExactSizeIterator for Entries<'a, T, B> {}
957
958#[derive(Educe)]
959#[educe(Clone)]
960pub struct IndexedEntries<'a, T, B> {
961 index: Option<&'a str>,
962 inner: Entries<'a, T, B>,
963}
964
965impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
966 type Item = IndexedEntryRef<'a, T, B>;
967
968 fn size_hint(&self) -> (usize, Option<usize>) {
969 let len = self.inner.len() + usize::from(self.index.is_some());
970 (len, Some(len))
971 }
972
973 fn next(&mut self) -> Option<Self::Item> {
974 self.index
975 .take()
976 .map(IndexedEntryRef::Index)
977 .or_else(|| self.inner.next().map(IndexedEntryRef::Node))
978 }
979}
980
981impl<'a, T, B> ExactSizeIterator for IndexedEntries<'a, T, B> {}
982
983#[derive(Educe, PartialEq, Eq)]
984#[educe(Clone, Copy)]
985pub enum IndexedEntryKeyRef<'a, T, B> {
986 Index,
987 Node(EntryKeyRef<'a, T, B>),
988}
989
990impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
991 pub fn into_keyword(self) -> Option<Keyword> {
992 match self {
993 Self::Index => Some(Keyword::Index),
994 Self::Node(e) => e.into_keyword(),
995 }
996 }
997
998 pub fn as_keyword(&self) -> Option<Keyword> {
999 self.into_keyword()
1000 }
1001
1002 pub fn into_str(self) -> &'a str
1003 where
1004 T: AsRef<str>,
1005 B: AsRef<str>,
1006 {
1007 match self {
1008 Self::Index => "@index",
1009 Self::Node(e) => e.into_str(),
1010 }
1011 }
1012
1013 pub fn as_str(&self) -> &'a str
1014 where
1015 T: AsRef<str>,
1016 B: AsRef<str>,
1017 {
1018 self.into_str()
1019 }
1020}
1021
1022impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N>
1023 for IndexedEntryKeyRef<'a, T, B>
1024{
1025 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
1026 match self {
1027 IndexedEntryKeyRef::Index => "@index",
1028 IndexedEntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
1029 }
1030 }
1031}
1032
1033#[derive(Educe)]
1034#[educe(Clone, Copy)]
1035pub enum IndexedEntryValueRef<'a, T, B> {
1036 Index(&'a str),
1037 Node(EntryValueRef<'a, T, B>),
1038}
1039
1040#[derive(Educe)]
1041#[educe(Clone, Copy)]
1042pub enum IndexedEntryRef<'a, T, B> {
1043 Index(&'a str),
1044 Node(EntryRef<'a, T, B>),
1045}
1046
1047impl<'a, T, B> IndexedEntryRef<'a, T, B> {
1048 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
1049 match self {
1050 Self::Index(_) => IndexedEntryKeyRef::Index,
1051 Self::Node(e) => IndexedEntryKeyRef::Node(e.key()),
1052 }
1053 }
1054
1055 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
1056 self.into_key()
1057 }
1058
1059 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
1060 match self {
1061 Self::Index(v) => IndexedEntryValueRef::Index(v),
1062 Self::Node(e) => IndexedEntryValueRef::Node(e.value()),
1063 }
1064 }
1065
1066 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
1067 self.into_value()
1068 }
1069
1070 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1071 match self {
1072 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
1073 Self::Node(e) => {
1074 let (k, v) = e.into_key_value();
1075 (IndexedEntryKeyRef::Node(k), IndexedEntryValueRef::Node(v))
1076 }
1077 }
1078 }
1079
1080 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1081 self.into_key_value()
1082 }
1083}
1084
1085pub enum FragmentRef<'a, T, B> {
1087 Entry(EntryRef<'a, T, B>),
1089
1090 Key(EntryKeyRef<'a, T, B>),
1092
1093 Value(EntryValueRef<'a, T, B>),
1095
1096 TypeFragment(&'a Id<T, B>),
1098}
1099
1100impl<'a, T, B> FragmentRef<'a, T, B> {
1101 pub fn into_id(self) -> Option<&'a Id<T, B>> {
1102 match self {
1103 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1104 Self::Value(EntryValueRef::Id(id)) => Some(id),
1105 Self::TypeFragment(ty) => Some(ty),
1106 _ => None,
1107 }
1108 }
1109
1110 pub fn as_id(&self) -> Option<&'a Id<T, B>> {
1111 match self {
1112 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1113 Self::Value(EntryValueRef::Id(id)) => Some(id),
1114 Self::TypeFragment(ty) => Some(ty),
1115 _ => None,
1116 }
1117 }
1118
1119 pub fn is_json_array(&self) -> bool {
1120 match self {
1121 Self::Value(v) => v.is_json_array(),
1122 _ => false,
1123 }
1124 }
1125
1126 pub fn is_json_object(&self) -> bool {
1127 match self {
1128 Self::Value(v) => v.is_json_object(),
1129 _ => false,
1130 }
1131 }
1132
1133 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1134 match self {
1135 Self::Entry(e) => SubFragments::Entry(Some(e.key()), Some(e.value())),
1136 Self::Value(v) => v.sub_fragments(),
1137 _ => SubFragments::None,
1138 }
1139 }
1140}
1141
1142pub enum SubFragments<'a, T, B> {
1143 None,
1144 Entry(
1145 Option<EntryKeyRef<'a, T, B>>,
1146 Option<EntryValueRef<'a, T, B>>,
1147 ),
1148 Type(std::slice::Iter<'a, Id<T, B>>),
1149 Graph(indexmap::set::Iter<'a, IndexedObject<T, B>>),
1150 Included(indexmap::set::Iter<'a, IndexedNode<T, B>>),
1151 Reverse(reverse_properties::Iter<'a, T, B>),
1152 Property(std::slice::Iter<'a, IndexedObject<T, B>>),
1153}
1154
1155impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1156 type Item = super::FragmentRef<'a, T, B>;
1157
1158 fn next(&mut self) -> Option<Self::Item> {
1159 match self {
1160 Self::None => None,
1161 Self::Entry(k, v) => k
1162 .take()
1163 .map(|k| super::FragmentRef::NodeFragment(FragmentRef::Key(k)))
1164 .or_else(|| {
1165 v.take()
1166 .map(|v| super::FragmentRef::NodeFragment(FragmentRef::Value(v)))
1167 }),
1168 Self::Type(l) => l
1169 .next_back()
1170 .map(|t| super::FragmentRef::NodeFragment(FragmentRef::TypeFragment(t))),
1171 Self::Graph(g) => g.next().map(|o| super::FragmentRef::IndexedObject(o)),
1172 Self::Included(i) => i.next().map(|n| super::FragmentRef::IndexedNode(n)),
1173 Self::Reverse(r) => r
1174 .next()
1175 .map(|(_, n)| super::FragmentRef::IndexedNodeList(n)),
1176 Self::Property(o) => o.next().map(|o| super::FragmentRef::IndexedObject(o)),
1177 }
1178 }
1179}
1180
1181impl<T, B> object::Any<T, B> for Node<T, B> {
1182 #[inline(always)]
1183 fn as_ref(&self) -> object::Ref<T, B> {
1184 object::Ref::Node(self)
1185 }
1186}
1187
1188impl<T, B> TryFrom<Object<T, B>> for Node<T, B> {
1189 type Error = Object<T, B>;
1190
1191 #[inline(always)]
1192 fn try_from(obj: Object<T, B>) -> Result<Node<T, B>, Object<T, B>> {
1193 match obj {
1194 Object::Node(node) => Ok(*node),
1195 obj => Err(obj),
1196 }
1197 }
1198}
1199
1200impl<T: Hash, B: Hash> Hash for Node<T, B> {
1201 #[inline]
1202 fn hash<H: Hasher>(&self, h: &mut H) {
1203 self.id.hash(h);
1204 utils::hash_set_opt(self.types.as_ref(), h);
1205 utils::hash_set_opt(self.graph.as_ref(), h);
1206 utils::hash_set_opt(self.included.as_ref(), h);
1207 self.properties.hash(h);
1208 self.reverse_properties.hash(h)
1209 }
1210}
1211
1212pub struct Nodes<'a, T, B>(Option<std::slice::Iter<'a, IndexedNode<T, B>>>);
1214
1215impl<'a, T, B> Nodes<'a, T, B> {
1216 #[inline(always)]
1217 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedNode<T, B>>>) -> Self {
1218 Self(inner)
1219 }
1220}
1221
1222impl<'a, T, B> Iterator for Nodes<'a, T, B> {
1223 type Item = &'a IndexedNode<T, B>;
1224
1225 #[inline(always)]
1226 fn next(&mut self) -> Option<&'a IndexedNode<T, B>> {
1227 match &mut self.0 {
1228 None => None,
1229 Some(it) => it.next(),
1230 }
1231 }
1232}
1233
1234impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Node<T, B> {
1235 fn try_from_json_object_in(
1236 vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>,
1237 mut object: json_syntax::Object,
1238 ) -> Result<Self, InvalidExpandedJson> {
1239 let id = match object
1240 .remove_unique("@id")
1241 .map_err(InvalidExpandedJson::duplicate_key)?
1242 {
1243 Some(entry) => Some(Id::try_from_json_in(vocabulary, entry.value)?),
1244 None => None,
1245 };
1246
1247 let types = match object
1248 .remove_unique("@type")
1249 .map_err(InvalidExpandedJson::duplicate_key)?
1250 {
1251 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1252 None => None,
1253 };
1254
1255 let graph = match object
1256 .remove_unique("@graph")
1257 .map_err(InvalidExpandedJson::duplicate_key)?
1258 {
1259 Some(entry) => Some(IndexSet::try_from_json_in(vocabulary, entry.value)?),
1260 None => None,
1261 };
1262
1263 let included = match object
1264 .remove_unique("@included")
1265 .map_err(InvalidExpandedJson::duplicate_key)?
1266 {
1267 Some(entry) => Some(IndexSet::try_from_json_in(vocabulary, entry.value)?),
1268 None => None,
1269 };
1270
1271 let reverse_properties = match object
1272 .remove_unique("@reverse")
1273 .map_err(InvalidExpandedJson::duplicate_key)?
1274 {
1275 Some(entry) => Some(ReverseProperties::try_from_json_in(
1276 vocabulary,
1277 entry.value,
1278 )?),
1279 None => None,
1280 };
1281
1282 let properties = Properties::try_from_json_object_in(vocabulary, object)?;
1283
1284 Ok(Self {
1285 id,
1286 types,
1287 graph,
1288 included,
1289 reverse_properties,
1290 properties,
1291 })
1292 }
1293}
1294
1295impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Node<T, B> {
1296 fn into_json_with(self, vocabulary: &N) -> json_syntax::Value {
1297 let mut obj = json_syntax::Object::new();
1298
1299 if let Some(id) = self.id {
1300 obj.insert("@id".into(), id.into_with(vocabulary).into_json());
1301 }
1302
1303 if let Some(types) = self.types {
1304 if !types.is_empty() {
1305 let value = types.into_with(vocabulary).into_json();
1311
1312 obj.insert("@type".into(), value);
1313 }
1314 }
1315
1316 if let Some(graph) = self.graph {
1317 obj.insert("@graph".into(), graph.into_with(vocabulary).into_json());
1318 }
1319
1320 if let Some(included) = self.included {
1321 obj.insert(
1322 "@include".into(),
1323 included.into_with(vocabulary).into_json(),
1324 );
1325 }
1326
1327 if let Some(reverse_properties) = self.reverse_properties {
1328 obj.insert(
1329 "@reverse".into(),
1330 reverse_properties.into_with(vocabulary).into_json(),
1331 );
1332 }
1333
1334 for (prop, objects) in self.properties {
1335 obj.insert(
1336 prop.with(vocabulary).to_string().into(),
1337 objects.into_json_with(vocabulary),
1338 );
1339 }
1340
1341 obj.into()
1342 }
1343}