1use super::{InvalidExpandedJson, Traverse, TryFromJson, TryFromJsonObject};
2use crate::{HashMap, Id, Indexed, IndexedObject, Object, Objects, Relabel, Term, ValidId, object, utils};
3use contextual::{IntoRefWithContext, WithContext};
4use derive_where::derive_where;
5use iri_rs::IriBuf;
6use jsonld_syntax::{IntoJson, IntoJsonWithContext, Keyword};
7use rdfx::{
8 BlankIdBuf,
9 LocalGenerator,
10 vocabulary::{Vocabulary, VocabularyMut},
11};
12use std::{
13 convert::TryFrom,
14 hash::{Hash, Hasher},
15};
16
17pub mod multiset;
19pub mod properties;
21pub mod reverse_properties;
23
24pub use multiset::Multiset;
25pub use properties::Properties;
26pub use reverse_properties::ReverseProperties;
27
28pub type Graph<T, B> = Vec<IndexedObject<T, B>>;
40
41pub type Included<T, B> = Vec<IndexedNode<T, B>>;
43
44pub type IndexedNode<T = IriBuf, B = BlankIdBuf> = Indexed<Node<T, B>>;
46
47#[derive(Debug, Clone)]
54pub struct Node<T = IriBuf, B = BlankIdBuf> {
55 pub id: Option<Id<T, B>>,
59
60 pub types: Option<Vec<Id<T, B>>>,
64
65 pub graph: Option<Graph<T, B>>,
69
70 pub included: Option<Included<T, B>>,
74
75 pub properties: Properties<T, B>,
79
80 pub reverse_properties: Option<ReverseProperties<T, B>>,
84}
85
86impl<T, B> Default for Node<T, B> {
87 #[inline(always)]
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93impl<T, B> Node<T, B> {
94 #[inline(always)]
96 #[must_use]
97 pub fn new() -> Self {
98 Self {
99 id: None,
100 types: None,
101 graph: None,
102 included: None,
103 properties: Properties::new(),
104 reverse_properties: None,
105 }
106 }
107
108 #[inline(always)]
110 pub fn with_id(id: Id<T, B>) -> Self {
111 Self {
112 id: Some(id),
113 types: None,
114 graph: None,
115 included: None,
116 properties: Properties::new(),
117 reverse_properties: None,
118 }
119 }
120
121 pub fn new_graph(id: Id<T, B>, graph: Graph<T, B>) -> Self {
123 Self {
124 id: Some(id),
125 types: None,
126 graph: Some(graph),
127 included: None,
128 properties: Properties::new(),
129 reverse_properties: None,
130 }
131 }
132
133 #[inline(always)]
137 pub fn reverse_properties_mut_or_default(&mut self) -> &mut ReverseProperties<T, B> {
138 self.reverse_properties.get_or_insert_with(ReverseProperties::default)
139 }
140
141 #[inline(always)]
145 pub fn included_mut_or_default(&mut self) -> &mut Included<T, B> {
146 self.included.get_or_insert_with(Included::default)
147 }
148
149 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 if self.id.is_none() {
165 self.id = Some(crate::id::generator_next_id(vocabulary, generator)?.into());
166 }
167
168 if let Some(graph) = self.graph_mut() {
169 for o in graph.iter_mut() {
170 o.identify_all_with(vocabulary, generator)?;
171 }
172 }
173
174 if let Some(included) = self.included_mut() {
175 for n in included.iter_mut() {
176 n.identify_all_with(vocabulary, generator)?;
177 }
178 }
179
180 for (_, objects) in self.properties_mut() {
181 for object in objects {
182 object.identify_all_with(vocabulary, generator)?;
183 }
184 }
185
186 if let Some(reverse_properties) = self.reverse_properties_mut() {
187 for (_, nodes) in reverse_properties.iter_mut() {
188 for node in nodes {
189 node.identify_all_with(vocabulary, generator)?;
190 }
191 }
192 }
193
194 Ok(())
195 }
196
197 pub fn identify_all<G: LocalGenerator>(&mut self, generator: &mut G) -> Result<(), crate::id::GeneratedIdError>
203 where
204 T: Eq + Hash,
205 B: Eq + Hash,
206 (): Vocabulary<Iri = T, BlankId = B>,
207 {
208 self.identify_all_with(&mut (), generator)
209 }
210
211 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
214 for (_, objects) in self.properties_mut() {
215 for object in objects {
216 object.canonicalize_with(buffer);
217 }
218 }
219
220 if let Some(reverse_properties) = self.reverse_properties_mut() {
221 for (_, nodes) in reverse_properties.iter_mut() {
222 for node in nodes {
223 node.canonicalize_with(buffer);
224 }
225 }
226 }
227 }
228
229 pub fn canonicalize(&mut self) {
231 let mut buffer = ryu_js::Buffer::new();
232 self.canonicalize_with(&mut buffer);
233 }
234
235 #[inline(always)]
238 pub fn as_iri(&self) -> Option<&T> {
239 if let Some(id) = &self.id { id.as_iri() } else { None }
240 }
241
242 #[inline(always)]
246 pub fn as_str(&self) -> Option<&str>
247 where
248 T: AsRef<str>,
249 {
250 match self.as_iri() {
251 Some(iri) => Some(iri.as_ref()),
252 None => None,
253 }
254 }
255
256 #[inline(always)]
259 pub fn types(&self) -> &[Id<T, B>] {
260 match self.types.as_ref() {
261 Some(entry) => entry,
262 None => &[],
263 }
264 }
265
266 #[inline(always)]
269 pub fn types_mut(&mut self) -> &mut [Id<T, B>] {
270 match self.types.as_mut() {
271 Some(entry) => entry,
272 None => &mut [],
273 }
274 }
275
276 pub fn types_mut_or_default(&mut self) -> &mut Vec<Id<T, B>> {
279 self.types.get_or_insert_with(Vec::new)
280 }
281
282 pub fn types_mut_or_insert(&mut self, value: Vec<Id<T, B>>) -> &mut Vec<Id<T, B>> {
285 self.types.get_or_insert(value)
286 }
287
288 pub fn types_mut_or_insert_with(&mut self, f: impl FnOnce() -> Vec<Id<T, B>>) -> &mut Vec<Id<T, B>> {
291 self.types.get_or_insert_with(f)
292 }
293
294 #[inline]
296 pub fn has_type<U>(&self, ty: &U) -> bool
297 where
298 Id<T, B>: PartialEq<U>,
299 {
300 for self_ty in self.types() {
301 if self_ty == ty {
302 return true;
303 }
304 }
305
306 false
307 }
308
309 #[inline]
313 pub fn is_empty(&self) -> bool {
314 self.types.is_none() && self.graph.is_none() && self.included.is_none() && self.properties.is_empty() && self.reverse_properties.is_none()
315 }
316
317 #[inline]
322 pub fn is_graph(&self) -> bool {
323 self.graph.is_some() && self.types.is_none() && self.included.is_none() && self.properties.is_empty() && self.reverse_properties.is_none()
324 }
325
326 #[inline(always)]
328 pub fn is_simple_graph(&self) -> bool {
329 self.id.is_none() && self.is_graph()
330 }
331
332 #[inline(always)]
337 pub fn graph(&self) -> Option<&Graph<T, B>> {
338 self.graph.as_ref()
339 }
340
341 #[inline(always)]
344 pub fn graph_mut(&mut self) -> Option<&mut Graph<T, B>> {
345 self.graph.as_mut()
346 }
347
348 #[inline(always)]
352 pub fn graph_entry(&self) -> Option<&Graph<T, B>> {
353 self.graph.as_ref()
354 }
355
356 #[inline(always)]
361 pub fn graph_entry_mut(&mut self) -> Option<&mut Graph<T, B>> {
362 self.graph.as_mut()
363 }
364
365 #[inline(always)]
367 pub fn set_graph_entry(&mut self, graph: Option<Graph<T, B>>) {
368 self.graph = graph;
369 }
370
371 #[inline(always)]
375 pub fn included_entry(&self) -> Option<&Included<T, B>> {
376 self.included.as_ref()
377 }
378
379 #[inline(always)]
383 pub fn included_entry_mut(&mut self) -> Option<&mut Included<T, B>> {
384 self.included.as_mut()
385 }
386
387 pub fn included(&self) -> Option<&Included<T, B>> {
389 self.included.as_ref()
390 }
391
392 pub fn included_mut(&mut self) -> Option<&mut Included<T, B>> {
394 self.included.as_mut()
395 }
396
397 #[inline(always)]
400 pub fn set_included(&mut self, included: Option<Included<T, B>>) {
401 self.included = included;
402 }
403
404 #[inline(always)]
406 pub fn properties(&self) -> &Properties<T, B> {
407 &self.properties
408 }
409
410 #[inline(always)]
412 pub fn properties_mut(&mut self) -> &mut Properties<T, B> {
413 &mut self.properties
414 }
415
416 #[inline(always)]
419 pub fn reverse_properties(&self) -> Option<&ReverseProperties<T, B>> {
420 self.reverse_properties.as_ref()
421 }
422
423 #[inline(always)]
426 pub fn reverse_properties_entry(&self) -> Option<&ReverseProperties<T, B>> {
427 self.reverse_properties.as_ref()
428 }
429
430 #[inline(always)]
433 pub fn reverse_properties_mut(&mut self) -> Option<&mut ReverseProperties<T, B>> {
434 self.reverse_properties.as_mut()
435 }
436
437 pub fn set_reverse_properties(&mut self, reverse_properties: Option<ReverseProperties<T, B>>) {
439 self.reverse_properties = reverse_properties;
440 }
441
442 #[inline]
447 pub fn is_unnamed_graph(&self) -> bool {
448 self.graph.is_some()
449 && self.id.is_none()
450 && self.types.is_none()
451 && self.included.is_none()
452 && self.properties.is_empty()
453 && self.reverse_properties.is_none()
454 }
455
456 #[inline(always)]
465 pub fn into_unnamed_graph(self: Box<Self>) -> Result<Graph<T, B>, Box<Self>> {
466 if self.is_unnamed_graph() {
467 Ok(unsafe { self.graph.unwrap_unchecked() })
469 } else {
470 Err(self)
471 }
472 }
473
474 pub fn traverse(&self) -> Traverse<'_, T, B> {
477 Traverse::new(Some(super::FragmentRef::Node(self)))
478 }
479
480 #[inline(always)]
481 pub fn count(&self, f: impl FnMut(&super::FragmentRef<T, B>) -> bool) -> usize {
483 self.traverse().filter(f).count()
484 }
485
486 pub fn entries(&self) -> Entries<'_, T, B> {
489 Entries {
490 id: self.id.as_ref(),
491 type_: self.types.as_deref(),
492 graph: self.graph.as_ref(),
493 included: self.included.as_ref(),
494 reverse: self.reverse_properties.as_ref(),
495 properties: self.properties.iter(),
496 }
497 }
498
499 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>) -> Node<U, C>
502 where
503 U: Eq + Hash,
504 C: Eq + Hash,
505 {
506 self.map_ids_with(&mut map_iri, &mut map_id)
507 }
508
509 pub(crate) 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>) -> Node<U, C>
510 where
511 U: Eq + Hash,
512 C: Eq + Hash,
513 {
514 Node {
515 id: self.id.map(&mut *map_id),
516 types: self.types.map(|t| t.into_iter().map(&mut *map_id).collect()),
517 graph: self
518 .graph
519 .map(|g| g.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect()),
520 included: self
521 .included
522 .map(|i| i.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect()),
523 properties: self
524 .properties
525 .into_iter()
526 .map(|(id, values)| {
527 (
528 map_id(id),
529 values.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect::<Vec<_>>(),
530 )
531 })
532 .collect(),
533 reverse_properties: self.reverse_properties.map(|r| {
534 r.into_iter()
535 .map(|(id, values)| {
536 (
537 map_id(id),
538 values.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect::<Vec<_>>(),
539 )
540 })
541 .collect()
542 }),
543 }
544 }
545}
546
547impl<T: Eq + Hash, B: Eq + Hash> Node<T, B> {
548 #[inline(always)]
562 pub fn has_key(&self, key: &Term<T, B>) -> bool {
563 match key {
564 Term::Keyword(Keyword::Id) => self.id.is_some(),
565 Term::Keyword(Keyword::Type) => self.types.is_some(),
566 Term::Keyword(Keyword::Graph) => self.graph.is_some(),
567 Term::Keyword(Keyword::Included) => self.included.is_some(),
568 Term::Keyword(Keyword::Reverse) => self.reverse_properties.is_some(),
569 Term::Id(prop) => self.properties.contains(prop),
570 _ => false,
571 }
572 }
573
574 #[inline(always)]
577 pub fn get<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(&self, prop: &Q) -> Objects<'_, T, B>
578 where
579 T: 'a,
580 {
581 self.properties.get(prop)
582 }
583
584 #[inline(always)]
590 pub fn get_any<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(&self, prop: &Q) -> Option<&IndexedObject<T, B>>
591 where
592 T: 'a,
593 {
594 self.properties.get_any(prop)
595 }
596
597 #[inline(always)]
599 pub fn insert(&mut self, prop: Id<T, B>, value: IndexedObject<T, B>) {
600 self.properties.insert(prop, value);
601 }
602
603 #[inline(always)]
609 pub fn insert_all<Objects: Iterator<Item = IndexedObject<T, B>>>(&mut self, prop: Id<T, B>, values: Objects) {
610 self.properties.insert_all(prop, values);
611 }
612
613 pub fn reverse_properties_or_insert(&mut self, props: ReverseProperties<T, B>) -> &mut ReverseProperties<T, B> {
616 self.reverse_properties.get_or_insert(props)
617 }
618
619 pub fn reverse_properties_or_default(&mut self) -> &mut ReverseProperties<T, B> {
622 self.reverse_properties.get_or_insert_with(ReverseProperties::default)
623 }
624
625 pub fn reverse_properties_or_insert_with(&mut self, f: impl FnOnce() -> ReverseProperties<T, B>) -> &mut ReverseProperties<T, B> {
628 self.reverse_properties.get_or_insert_with(f)
629 }
630
631 pub fn equivalent(&self, other: &Self) -> bool {
637 if self.id.is_some() && other.id.is_some() { self == other } else { false }
638 }
639}
640
641impl<T, B> Relabel<T, B> for Node<T, B> {
642 fn relabel_with<N: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
643 &mut self,
644 vocabulary: &mut N,
645 generator: &mut G,
646 relabeling: &mut HashMap<B, ValidId<T, B>>,
647 ) -> Result<(), crate::id::GeneratedIdError>
648 where
649 T: Clone + Eq + Hash,
650 B: Clone + Eq + Hash,
651 {
652 self.id = match self.id.take() {
653 Some(Id::Valid(ValidId::Blank(b))) => {
654 let value = match relabeling.entry(b) {
655 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
656 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
657 };
658 Some(value.into())
659 }
660 None => {
661 let value = crate::id::generator_next_id(vocabulary, generator)?;
662 Some(value.into())
663 }
664 id => id,
665 };
666
667 for ty in self.types_mut() {
668 if let Some(b) = ty.as_blank().cloned() {
669 let value = match relabeling.entry(b) {
670 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
671 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
672 };
673 *ty = value.into();
674 }
675 }
676
677 if let Some(graph) = self.graph_mut() {
678 for o in graph.iter_mut() {
679 o.relabel_with(vocabulary, generator, relabeling)?;
680 }
681 }
682
683 if let Some(included) = self.included_mut() {
684 for n in included.iter_mut() {
685 n.relabel_with(vocabulary, generator, relabeling)?;
686 }
687 }
688
689 if !self.properties.is_empty() {
695 let properties = std::mem::take(&mut self.properties);
696 for (property, mut objects) in properties {
697 let property = match property {
698 Id::Valid(ValidId::Blank(b)) => {
699 let value = match relabeling.entry(b) {
700 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
701 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
702 };
703 value.into()
704 }
705 property => property,
706 };
707
708 for object in &mut objects {
709 object.relabel_with(vocabulary, generator, relabeling)?;
710 }
711
712 self.properties.set(property, objects);
713 }
714 }
715
716 if let Some(reverse_properties) = self.reverse_properties_mut() {
717 for (_, nodes) in reverse_properties.iter_mut() {
718 for node in nodes {
719 node.relabel_with(vocabulary, generator, relabeling)?;
720 }
721 }
722 }
723
724 Ok(())
725 }
726}
727
728impl<T: Eq + Hash, B: Eq + Hash> PartialEq for Node<T, B> {
729 fn eq(&self, other: &Self) -> bool {
730 self.id.eq(&other.id)
734 && multiset::compare_unordered_opt(self.types.as_deref(), other.types.as_deref())
735 && multiset::compare_unordered_opt(self.graph.as_deref(), other.graph.as_deref())
736 && multiset::compare_unordered_opt(self.included.as_deref(), other.included.as_deref())
737 && self.properties.eq(&other.properties)
738 && self.reverse_properties.eq(&other.reverse_properties)
739 }
740}
741
742impl<T: Eq + Hash, B: Eq + Hash> Eq for Node<T, B> {}
743
744impl<T, B> Indexed<Node<T, B>> {
745 pub fn entries(&self) -> IndexedEntries<'_, T, B> {
748 IndexedEntries {
749 index: self.index(),
750 inner: self.inner().entries(),
751 }
752 }
753}
754
755impl<T: Eq + Hash, B: Eq + Hash> Indexed<Node<T, B>> {
756 pub fn equivalent(&self, other: &Self) -> bool {
759 self.index() == other.index() && self.inner().equivalent(other.inner())
760 }
761}
762
763#[derive(PartialEq, Eq)]
769#[derive_where(Clone, Copy)]
770pub enum EntryKeyRef<'a, T, B> {
772 Id,
774 Type,
776 Graph,
778 Included,
780 Reverse,
782 Property(&'a Id<T, B>),
784}
785
786impl<'a, T, B> EntryKeyRef<'a, T, B> {
787 #[must_use]
789 pub fn into_keyword(self) -> Option<Keyword> {
790 match self {
791 Self::Id => Some(Keyword::Id),
792 Self::Type => Some(Keyword::Type),
793 Self::Graph => Some(Keyword::Graph),
794 Self::Included => Some(Keyword::Included),
795 Self::Reverse => Some(Keyword::Reverse),
796 Self::Property(_) => None,
797 }
798 }
799
800 #[must_use]
802 pub fn as_keyword(&self) -> Option<Keyword> {
803 self.into_keyword()
804 }
805
806 #[must_use]
808 pub fn into_str(self) -> &'a str
809 where
810 T: AsRef<str>,
811 B: AsRef<str>,
812 {
813 match self {
814 Self::Id => "@id",
815 Self::Type => "@type",
816 Self::Graph => "@graph",
817 Self::Included => "@included",
818 Self::Reverse => "@reverse",
819 Self::Property(p) => p.as_str(),
820 }
821 }
822
823 #[must_use]
825 pub fn as_str(&self) -> &'a str
826 where
827 T: AsRef<str>,
828 B: AsRef<str>,
829 {
830 self.into_str()
831 }
832}
833
834impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for EntryKeyRef<'a, T, B> {
835 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
836 match self {
837 EntryKeyRef::Id => "@id",
838 EntryKeyRef::Type => "@type",
839 EntryKeyRef::Graph => "@graph",
840 EntryKeyRef::Included => "@included",
841 EntryKeyRef::Reverse => "@reverse",
842 EntryKeyRef::Property(p) => p.with(vocabulary).as_str(),
843 }
844 }
845}
846
847#[derive_where(Clone, Copy)]
848pub enum EntryValueRef<'a, T, B> {
850 Id(&'a Id<T, B>),
852 Type(&'a [Id<T, B>]),
854 Graph(&'a Graph<T, B>),
856 Included(&'a Included<T, B>),
858 Reverse(&'a ReverseProperties<T, B>),
860 Property(&'a [IndexedObject<T, B>]),
862}
863
864impl<'a, T, B> EntryValueRef<'a, T, B> {
865 #[must_use]
867 pub fn is_json_array(&self) -> bool {
868 matches!(self, Self::Type(_) | Self::Graph(_) | Self::Included(_) | Self::Property(_))
869 }
870
871 #[must_use]
873 pub fn is_json_object(&self) -> bool {
874 matches!(self, Self::Reverse(_))
875 }
876
877 fn sub_fragments(&self) -> SubFragments<'a, T, B> {
878 match self {
879 Self::Type(l) => SubFragments::Type(l.iter()),
880 Self::Graph(g) => SubFragments::Graph(g.iter()),
881 Self::Included(i) => SubFragments::Included(i.iter()),
882 Self::Reverse(r) => SubFragments::Reverse(r.iter()),
883 Self::Property(p) => SubFragments::Property(p.iter()),
884 Self::Id(_) => SubFragments::None,
885 }
886 }
887}
888
889#[derive_where(Clone, Copy)]
890pub enum EntryRef<'a, T, B> {
892 Id(&'a Id<T, B>),
894 Type(&'a [Id<T, B>]),
896 Graph(&'a Graph<T, B>),
898 Included(&'a Included<T, B>),
900 Reverse(&'a ReverseProperties<T, B>),
902 Property(&'a Id<T, B>, &'a [IndexedObject<T, B>]),
904}
905
906impl<'a, T, B> EntryRef<'a, T, B> {
907 #[must_use]
909 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
910 match self {
911 Self::Id(_) => EntryKeyRef::Id,
912 Self::Type(_) => EntryKeyRef::Type,
913 Self::Graph(_) => EntryKeyRef::Graph,
914 Self::Included(_) => EntryKeyRef::Included,
915 Self::Reverse(_) => EntryKeyRef::Reverse,
916 Self::Property(k, _) => EntryKeyRef::Property(k),
917 }
918 }
919
920 #[must_use]
922 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
923 self.into_key()
924 }
925
926 #[must_use]
928 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
929 match self {
930 Self::Id(v) => EntryValueRef::Id(v),
931 Self::Type(v) => EntryValueRef::Type(v),
932 Self::Graph(v) => EntryValueRef::Graph(v),
933 Self::Included(v) => EntryValueRef::Included(v),
934 Self::Reverse(v) => EntryValueRef::Reverse(v),
935 Self::Property(_, v) => EntryValueRef::Property(v),
936 }
937 }
938
939 #[must_use]
941 pub fn value(&self) -> EntryValueRef<'a, T, B> {
942 self.into_value()
943 }
944
945 #[must_use]
947 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
948 match self {
949 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(v)),
950 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
951 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(v)),
952 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(v)),
953 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(v)),
954 Self::Property(k, v) => (EntryKeyRef::Property(k), EntryValueRef::Property(v)),
955 }
956 }
957
958 #[must_use]
960 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
961 match self {
962 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(*v)),
963 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
964 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(*v)),
965 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(*v)),
966 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(*v)),
967 Self::Property(k, v) => (EntryKeyRef::Property(*k), EntryValueRef::Property(v)),
968 }
969 }
970}
971
972#[derive_where(Clone)]
973pub struct Entries<'a, T, B> {
975 id: Option<&'a Id<T, B>>,
976 type_: Option<&'a [Id<T, B>]>,
977 graph: Option<&'a Graph<T, B>>,
978 included: Option<&'a Included<T, B>>,
979 reverse: Option<&'a ReverseProperties<T, B>>,
980 properties: properties::Iter<'a, T, B>,
981}
982
983impl<'a, T, B> Iterator for Entries<'a, T, B> {
984 type Item = EntryRef<'a, T, B>;
985
986 fn size_hint(&self) -> (usize, Option<usize>) {
987 let mut len = self.properties.len();
988
989 if self.id.is_some() {
990 len += 1;
991 }
992
993 if self.type_.is_some() {
994 len += 1;
995 }
996
997 if self.graph.is_some() {
998 len += 1;
999 }
1000
1001 if self.included.is_some() {
1002 len += 1;
1003 }
1004
1005 if self.reverse.is_some() {
1006 len += 1;
1007 }
1008
1009 (len, Some(len))
1010 }
1011
1012 fn next(&mut self) -> Option<Self::Item> {
1013 self.id.take().map(EntryRef::Id).or_else(|| {
1014 self.type_.take().map(EntryRef::Type).or_else(|| {
1015 self.graph.take().map(EntryRef::Graph).or_else(|| {
1016 self.included.take().map(EntryRef::Included).or_else(|| {
1017 self.reverse
1018 .take()
1019 .map(EntryRef::Reverse)
1020 .or_else(|| self.properties.next().map(|(k, v)| EntryRef::Property(k, v)))
1021 })
1022 })
1023 })
1024 })
1025 }
1026}
1027
1028impl<T, B> ExactSizeIterator for Entries<'_, T, B> {}
1029
1030#[derive_where(Clone)]
1031pub struct IndexedEntries<'a, T, B> {
1033 index: Option<&'a str>,
1034 inner: Entries<'a, T, B>,
1035}
1036
1037impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
1038 type Item = IndexedEntryRef<'a, T, B>;
1039
1040 fn size_hint(&self) -> (usize, Option<usize>) {
1041 let len = self.inner.len() + usize::from(self.index.is_some());
1042 (len, Some(len))
1043 }
1044
1045 fn next(&mut self) -> Option<Self::Item> {
1046 self.index
1047 .take()
1048 .map(IndexedEntryRef::Index)
1049 .or_else(|| self.inner.next().map(IndexedEntryRef::Node))
1050 }
1051}
1052
1053impl<T, B> ExactSizeIterator for IndexedEntries<'_, T, B> {}
1054
1055#[derive(PartialEq, Eq)]
1056#[derive_where(Clone, Copy)]
1057pub enum IndexedEntryKeyRef<'a, T, B> {
1059 Index,
1061 Node(EntryKeyRef<'a, T, B>),
1063}
1064
1065impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
1066 #[must_use]
1068 pub fn into_keyword(self) -> Option<Keyword> {
1069 match self {
1070 Self::Index => Some(Keyword::Index),
1071 Self::Node(e) => e.into_keyword(),
1072 }
1073 }
1074
1075 #[must_use]
1077 pub fn as_keyword(&self) -> Option<Keyword> {
1078 self.into_keyword()
1079 }
1080
1081 #[must_use]
1083 pub fn into_str(self) -> &'a str
1084 where
1085 T: AsRef<str>,
1086 B: AsRef<str>,
1087 {
1088 match self {
1089 Self::Index => "@index",
1090 Self::Node(e) => e.into_str(),
1091 }
1092 }
1093
1094 #[must_use]
1096 pub fn as_str(&self) -> &'a str
1097 where
1098 T: AsRef<str>,
1099 B: AsRef<str>,
1100 {
1101 self.into_str()
1102 }
1103}
1104
1105impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for IndexedEntryKeyRef<'a, T, B> {
1106 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
1107 match self {
1108 IndexedEntryKeyRef::Index => "@index",
1109 IndexedEntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
1110 }
1111 }
1112}
1113
1114#[derive_where(Clone, Copy)]
1115pub enum IndexedEntryValueRef<'a, T, B> {
1117 Index(&'a str),
1119 Node(EntryValueRef<'a, T, B>),
1121}
1122
1123#[derive_where(Clone, Copy)]
1124pub enum IndexedEntryRef<'a, T, B> {
1126 Index(&'a str),
1128 Node(EntryRef<'a, T, B>),
1130}
1131
1132impl<'a, T, B> IndexedEntryRef<'a, T, B> {
1133 #[must_use]
1135 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
1136 match self {
1137 Self::Index(_) => IndexedEntryKeyRef::Index,
1138 Self::Node(e) => IndexedEntryKeyRef::Node(e.key()),
1139 }
1140 }
1141
1142 #[must_use]
1144 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
1145 self.into_key()
1146 }
1147
1148 #[must_use]
1150 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
1151 match self {
1152 Self::Index(v) => IndexedEntryValueRef::Index(v),
1153 Self::Node(e) => IndexedEntryValueRef::Node(e.value()),
1154 }
1155 }
1156
1157 #[must_use]
1159 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
1160 self.into_value()
1161 }
1162
1163 #[must_use]
1165 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1166 match self {
1167 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
1168 Self::Node(e) => {
1169 let (k, v) = e.into_key_value();
1170 (IndexedEntryKeyRef::Node(k), IndexedEntryValueRef::Node(v))
1171 }
1172 }
1173 }
1174
1175 #[must_use]
1177 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1178 self.into_key_value()
1179 }
1180}
1181
1182pub enum FragmentRef<'a, T, B> {
1184 Entry(EntryRef<'a, T, B>),
1186
1187 Key(EntryKeyRef<'a, T, B>),
1189
1190 Value(EntryValueRef<'a, T, B>),
1192
1193 TypeFragment(&'a Id<T, B>),
1195}
1196
1197impl<'a, T, B> FragmentRef<'a, T, B> {
1198 #[must_use]
1200 pub fn into_id(self) -> Option<&'a Id<T, B>> {
1201 match self {
1202 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1203 Self::Value(EntryValueRef::Id(id)) => Some(id),
1204 Self::TypeFragment(ty) => Some(ty),
1205 _ => None,
1206 }
1207 }
1208
1209 #[must_use]
1211 pub fn as_id(&self) -> Option<&'a Id<T, B>> {
1212 match self {
1213 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1214 Self::Value(EntryValueRef::Id(id)) => Some(id),
1215 Self::TypeFragment(ty) => Some(ty),
1216 _ => None,
1217 }
1218 }
1219
1220 #[must_use]
1222 pub fn is_json_array(&self) -> bool {
1223 match self {
1224 Self::Value(v) => v.is_json_array(),
1225 _ => false,
1226 }
1227 }
1228
1229 #[must_use]
1231 pub fn is_json_object(&self) -> bool {
1232 match self {
1233 Self::Value(v) => v.is_json_object(),
1234 _ => false,
1235 }
1236 }
1237
1238 #[must_use]
1240 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1241 match self {
1242 Self::Entry(e) => SubFragments::Entry(Some(e.key()), Some(e.value())),
1243 Self::Value(v) => v.sub_fragments(),
1244 _ => SubFragments::None,
1245 }
1246 }
1247}
1248
1249pub enum SubFragments<'a, T, B> {
1251 None,
1253 Entry(Option<EntryKeyRef<'a, T, B>>, Option<EntryValueRef<'a, T, B>>),
1255 Type(std::slice::Iter<'a, Id<T, B>>),
1257 Graph(std::slice::Iter<'a, IndexedObject<T, B>>),
1259 Included(std::slice::Iter<'a, IndexedNode<T, B>>),
1261 Reverse(reverse_properties::Iter<'a, T, B>),
1263 Property(std::slice::Iter<'a, IndexedObject<T, B>>),
1265}
1266
1267impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1268 type Item = super::FragmentRef<'a, T, B>;
1269
1270 fn next(&mut self) -> Option<Self::Item> {
1271 match self {
1272 Self::None => None,
1273 Self::Entry(k, v) => k
1274 .take()
1275 .map(|k| super::FragmentRef::NodeFragment(FragmentRef::Key(k)))
1276 .or_else(|| v.take().map(|v| super::FragmentRef::NodeFragment(FragmentRef::Value(v)))),
1277 Self::Type(l) => l.next_back().map(|t| super::FragmentRef::NodeFragment(FragmentRef::TypeFragment(t))),
1278 Self::Graph(g) => g.next().map(|o| super::FragmentRef::IndexedObject(o)),
1279 Self::Included(i) => i.next().map(|n| super::FragmentRef::IndexedNode(n)),
1280 Self::Reverse(r) => r.next().map(|(_, n)| super::FragmentRef::IndexedNodeList(n)),
1281 Self::Property(o) => o.next().map(|o| super::FragmentRef::IndexedObject(o)),
1282 }
1283 }
1284}
1285
1286impl<T, B> object::Any<T, B> for Node<T, B> {
1287 #[inline(always)]
1288 fn as_ref(&self) -> object::Ref<'_, T, B> {
1289 object::Ref::Node(self)
1290 }
1291}
1292
1293impl<T, B> TryFrom<Object<T, B>> for Node<T, B> {
1294 type Error = Object<T, B>;
1295
1296 #[inline(always)]
1297 fn try_from(obj: Object<T, B>) -> Result<Node<T, B>, Object<T, B>> {
1298 match obj {
1299 Object::Node(node) => Ok(*node),
1300 obj => Err(obj),
1301 }
1302 }
1303}
1304
1305impl<T: Hash, B: Hash> Hash for Node<T, B> {
1306 #[inline]
1307 fn hash<H: Hasher>(&self, h: &mut H) {
1308 self.id.hash(h);
1309 utils::hash_set_opt(self.types.as_ref(), h);
1310 utils::hash_set_opt(self.graph.as_ref(), h);
1311 utils::hash_set_opt(self.included.as_ref(), h);
1312 self.properties.hash(h);
1313 self.reverse_properties.hash(h);
1314 }
1315}
1316
1317pub struct Nodes<'a, T, B>(Option<std::slice::Iter<'a, IndexedNode<T, B>>>);
1319
1320impl<'a, T, B> Nodes<'a, T, B> {
1321 #[inline(always)]
1322 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedNode<T, B>>>) -> Self {
1323 Self(inner)
1324 }
1325}
1326
1327impl<'a, T, B> Iterator for Nodes<'a, T, B> {
1328 type Item = &'a IndexedNode<T, B>;
1329
1330 #[inline(always)]
1331 fn next(&mut self) -> Option<&'a IndexedNode<T, B>> {
1332 match &mut self.0 {
1333 None => None,
1334 Some(it) => it.next(),
1335 }
1336 }
1337}
1338
1339impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Node<T, B> {
1340 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, mut object: jstrict::Object) -> Result<Self, InvalidExpandedJson> {
1341 let id = match object.remove_unique("@id").map_err(InvalidExpandedJson::duplicate_key)? {
1342 Some(entry) => Some(Id::try_from_json_in(vocabulary, entry.value)?),
1343 None => None,
1344 };
1345
1346 let types = match object.remove_unique("@type").map_err(InvalidExpandedJson::duplicate_key)? {
1347 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1348 None => None,
1349 };
1350
1351 let graph = match object.remove_unique("@graph").map_err(InvalidExpandedJson::duplicate_key)? {
1352 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1353 None => None,
1354 };
1355
1356 let included = match object.remove_unique("@included").map_err(InvalidExpandedJson::duplicate_key)? {
1357 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1358 None => None,
1359 };
1360
1361 let reverse_properties = match object.remove_unique("@reverse").map_err(InvalidExpandedJson::duplicate_key)? {
1362 Some(entry) => Some(ReverseProperties::try_from_json_in(vocabulary, entry.value)?),
1363 None => None,
1364 };
1365
1366 let properties = Properties::try_from_json_object_in(vocabulary, object)?;
1367
1368 Ok(Self {
1369 id,
1370 types,
1371 graph,
1372 included,
1373 properties,
1374 reverse_properties,
1375 })
1376 }
1377}
1378
1379impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Node<T, B> {
1380 fn into_json_with(self, vocabulary: &N) -> jstrict::Value {
1381 let mut obj = jstrict::Object::new();
1382
1383 if let Some(id) = self.id {
1384 obj.insert("@id".into(), id.into_with(vocabulary).into_json());
1385 }
1386
1387 if let Some(types) = self.types
1388 && !types.is_empty()
1389 {
1390 let value = types.into_with(vocabulary).into_json();
1391
1392 obj.insert("@type".into(), value);
1393 }
1394
1395 if let Some(graph) = self.graph {
1396 obj.insert("@graph".into(), graph.into_with(vocabulary).into_json());
1397 }
1398
1399 if let Some(included) = self.included {
1400 obj.insert("@included".into(), included.into_with(vocabulary).into_json());
1401 }
1402
1403 if let Some(reverse_properties) = self.reverse_properties {
1404 obj.insert("@reverse".into(), reverse_properties.into_with(vocabulary).into_json());
1405 }
1406
1407 for (prop, objects) in self.properties {
1408 obj.insert(prop.with(vocabulary).to_string().into(), objects.into_json_with(vocabulary));
1409 }
1410
1411 obj.into()
1412 }
1413}