1use super::{InvalidExpandedJson, Traverse, TryFromJson, TryFromJsonObject};
2use crate::{HashMap, Id, Indexed, IndexedObject, Object, Objects, Relabel, Term, ValidId, object, utils};
3use contextual::{IntoRefWithContext, WithContext};
4use educe::Educe;
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(Educe, PartialEq, Eq)]
769#[educe(Clone(bound(false)), Copy(bound(false)))]
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(Educe)]
848#[educe(Clone(bound(false)), Copy(bound(false)))]
849pub enum EntryValueRef<'a, T, B> {
851 Id(&'a Id<T, B>),
853 Type(&'a [Id<T, B>]),
855 Graph(&'a Graph<T, B>),
857 Included(&'a Included<T, B>),
859 Reverse(&'a ReverseProperties<T, B>),
861 Property(&'a [IndexedObject<T, B>]),
863}
864
865impl<'a, T, B> EntryValueRef<'a, T, B> {
866 #[must_use]
868 pub fn is_json_array(&self) -> bool {
869 matches!(self, Self::Type(_) | Self::Graph(_) | Self::Included(_) | Self::Property(_))
870 }
871
872 #[must_use]
874 pub fn is_json_object(&self) -> bool {
875 matches!(self, Self::Reverse(_))
876 }
877
878 fn sub_fragments(&self) -> SubFragments<'a, T, B> {
879 match self {
880 Self::Type(l) => SubFragments::Type(l.iter()),
881 Self::Graph(g) => SubFragments::Graph(g.iter()),
882 Self::Included(i) => SubFragments::Included(i.iter()),
883 Self::Reverse(r) => SubFragments::Reverse(r.iter()),
884 Self::Property(p) => SubFragments::Property(p.iter()),
885 Self::Id(_) => SubFragments::None,
886 }
887 }
888}
889
890#[derive(Educe)]
891#[educe(Clone(bound(false)), Copy(bound(false)))]
892pub enum EntryRef<'a, T, B> {
894 Id(&'a Id<T, B>),
896 Type(&'a [Id<T, B>]),
898 Graph(&'a Graph<T, B>),
900 Included(&'a Included<T, B>),
902 Reverse(&'a ReverseProperties<T, B>),
904 Property(&'a Id<T, B>, &'a [IndexedObject<T, B>]),
906}
907
908impl<'a, T, B> EntryRef<'a, T, B> {
909 #[must_use]
911 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
912 match self {
913 Self::Id(_) => EntryKeyRef::Id,
914 Self::Type(_) => EntryKeyRef::Type,
915 Self::Graph(_) => EntryKeyRef::Graph,
916 Self::Included(_) => EntryKeyRef::Included,
917 Self::Reverse(_) => EntryKeyRef::Reverse,
918 Self::Property(k, _) => EntryKeyRef::Property(k),
919 }
920 }
921
922 #[must_use]
924 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
925 self.into_key()
926 }
927
928 #[must_use]
930 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
931 match self {
932 Self::Id(v) => EntryValueRef::Id(v),
933 Self::Type(v) => EntryValueRef::Type(v),
934 Self::Graph(v) => EntryValueRef::Graph(v),
935 Self::Included(v) => EntryValueRef::Included(v),
936 Self::Reverse(v) => EntryValueRef::Reverse(v),
937 Self::Property(_, v) => EntryValueRef::Property(v),
938 }
939 }
940
941 #[must_use]
943 pub fn value(&self) -> EntryValueRef<'a, T, B> {
944 self.into_value()
945 }
946
947 #[must_use]
949 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
950 match self {
951 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(v)),
952 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
953 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(v)),
954 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(v)),
955 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(v)),
956 Self::Property(k, v) => (EntryKeyRef::Property(k), EntryValueRef::Property(v)),
957 }
958 }
959
960 #[must_use]
962 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
963 match self {
964 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(*v)),
965 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
966 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(*v)),
967 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(*v)),
968 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(*v)),
969 Self::Property(k, v) => (EntryKeyRef::Property(*k), EntryValueRef::Property(v)),
970 }
971 }
972}
973
974#[derive(Educe)]
975#[educe(Clone)]
976pub struct Entries<'a, T, B> {
978 id: Option<&'a Id<T, B>>,
979 type_: Option<&'a [Id<T, B>]>,
980 graph: Option<&'a Graph<T, B>>,
981 included: Option<&'a Included<T, B>>,
982 reverse: Option<&'a ReverseProperties<T, B>>,
983 properties: properties::Iter<'a, T, B>,
984}
985
986impl<'a, T, B> Iterator for Entries<'a, T, B> {
987 type Item = EntryRef<'a, T, B>;
988
989 fn size_hint(&self) -> (usize, Option<usize>) {
990 let mut len = self.properties.len();
991
992 if self.id.is_some() {
993 len += 1;
994 }
995
996 if self.type_.is_some() {
997 len += 1;
998 }
999
1000 if self.graph.is_some() {
1001 len += 1;
1002 }
1003
1004 if self.included.is_some() {
1005 len += 1;
1006 }
1007
1008 if self.reverse.is_some() {
1009 len += 1;
1010 }
1011
1012 (len, Some(len))
1013 }
1014
1015 fn next(&mut self) -> Option<Self::Item> {
1016 self.id.take().map(EntryRef::Id).or_else(|| {
1017 self.type_.take().map(EntryRef::Type).or_else(|| {
1018 self.graph.take().map(EntryRef::Graph).or_else(|| {
1019 self.included.take().map(EntryRef::Included).or_else(|| {
1020 self.reverse
1021 .take()
1022 .map(EntryRef::Reverse)
1023 .or_else(|| self.properties.next().map(|(k, v)| EntryRef::Property(k, v)))
1024 })
1025 })
1026 })
1027 })
1028 }
1029}
1030
1031impl<T, B> ExactSizeIterator for Entries<'_, T, B> {}
1032
1033#[derive(Educe)]
1034#[educe(Clone)]
1035pub struct IndexedEntries<'a, T, B> {
1037 index: Option<&'a str>,
1038 inner: Entries<'a, T, B>,
1039}
1040
1041impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
1042 type Item = IndexedEntryRef<'a, T, B>;
1043
1044 fn size_hint(&self) -> (usize, Option<usize>) {
1045 let len = self.inner.len() + usize::from(self.index.is_some());
1046 (len, Some(len))
1047 }
1048
1049 fn next(&mut self) -> Option<Self::Item> {
1050 self.index
1051 .take()
1052 .map(IndexedEntryRef::Index)
1053 .or_else(|| self.inner.next().map(IndexedEntryRef::Node))
1054 }
1055}
1056
1057impl<T, B> ExactSizeIterator for IndexedEntries<'_, T, B> {}
1058
1059#[derive(Educe, PartialEq, Eq)]
1060#[educe(Clone(bound(false)), Copy(bound(false)))]
1061pub enum IndexedEntryKeyRef<'a, T, B> {
1063 Index,
1065 Node(EntryKeyRef<'a, T, B>),
1067}
1068
1069impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
1070 #[must_use]
1072 pub fn into_keyword(self) -> Option<Keyword> {
1073 match self {
1074 Self::Index => Some(Keyword::Index),
1075 Self::Node(e) => e.into_keyword(),
1076 }
1077 }
1078
1079 #[must_use]
1081 pub fn as_keyword(&self) -> Option<Keyword> {
1082 self.into_keyword()
1083 }
1084
1085 #[must_use]
1087 pub fn into_str(self) -> &'a str
1088 where
1089 T: AsRef<str>,
1090 B: AsRef<str>,
1091 {
1092 match self {
1093 Self::Index => "@index",
1094 Self::Node(e) => e.into_str(),
1095 }
1096 }
1097
1098 #[must_use]
1100 pub fn as_str(&self) -> &'a str
1101 where
1102 T: AsRef<str>,
1103 B: AsRef<str>,
1104 {
1105 self.into_str()
1106 }
1107}
1108
1109impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for IndexedEntryKeyRef<'a, T, B> {
1110 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
1111 match self {
1112 IndexedEntryKeyRef::Index => "@index",
1113 IndexedEntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
1114 }
1115 }
1116}
1117
1118#[derive(Educe)]
1119#[educe(Clone(bound(false)), Copy(bound(false)))]
1120pub enum IndexedEntryValueRef<'a, T, B> {
1122 Index(&'a str),
1124 Node(EntryValueRef<'a, T, B>),
1126}
1127
1128#[derive(Educe)]
1129#[educe(Clone(bound(false)), Copy(bound(false)))]
1130pub enum IndexedEntryRef<'a, T, B> {
1132 Index(&'a str),
1134 Node(EntryRef<'a, T, B>),
1136}
1137
1138impl<'a, T, B> IndexedEntryRef<'a, T, B> {
1139 #[must_use]
1141 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
1142 match self {
1143 Self::Index(_) => IndexedEntryKeyRef::Index,
1144 Self::Node(e) => IndexedEntryKeyRef::Node(e.key()),
1145 }
1146 }
1147
1148 #[must_use]
1150 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
1151 self.into_key()
1152 }
1153
1154 #[must_use]
1156 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
1157 match self {
1158 Self::Index(v) => IndexedEntryValueRef::Index(v),
1159 Self::Node(e) => IndexedEntryValueRef::Node(e.value()),
1160 }
1161 }
1162
1163 #[must_use]
1165 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
1166 self.into_value()
1167 }
1168
1169 #[must_use]
1171 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1172 match self {
1173 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
1174 Self::Node(e) => {
1175 let (k, v) = e.into_key_value();
1176 (IndexedEntryKeyRef::Node(k), IndexedEntryValueRef::Node(v))
1177 }
1178 }
1179 }
1180
1181 #[must_use]
1183 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1184 self.into_key_value()
1185 }
1186}
1187
1188pub enum FragmentRef<'a, T, B> {
1190 Entry(EntryRef<'a, T, B>),
1192
1193 Key(EntryKeyRef<'a, T, B>),
1195
1196 Value(EntryValueRef<'a, T, B>),
1198
1199 TypeFragment(&'a Id<T, B>),
1201}
1202
1203impl<'a, T, B> FragmentRef<'a, T, B> {
1204 #[must_use]
1206 pub fn into_id(self) -> Option<&'a Id<T, B>> {
1207 match self {
1208 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1209 Self::Value(EntryValueRef::Id(id)) => Some(id),
1210 Self::TypeFragment(ty) => Some(ty),
1211 _ => None,
1212 }
1213 }
1214
1215 #[must_use]
1217 pub fn as_id(&self) -> Option<&'a Id<T, B>> {
1218 match self {
1219 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1220 Self::Value(EntryValueRef::Id(id)) => Some(id),
1221 Self::TypeFragment(ty) => Some(ty),
1222 _ => None,
1223 }
1224 }
1225
1226 #[must_use]
1228 pub fn is_json_array(&self) -> bool {
1229 match self {
1230 Self::Value(v) => v.is_json_array(),
1231 _ => false,
1232 }
1233 }
1234
1235 #[must_use]
1237 pub fn is_json_object(&self) -> bool {
1238 match self {
1239 Self::Value(v) => v.is_json_object(),
1240 _ => false,
1241 }
1242 }
1243
1244 #[must_use]
1246 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1247 match self {
1248 Self::Entry(e) => SubFragments::Entry(Some(e.key()), Some(e.value())),
1249 Self::Value(v) => v.sub_fragments(),
1250 _ => SubFragments::None,
1251 }
1252 }
1253}
1254
1255pub enum SubFragments<'a, T, B> {
1257 None,
1259 Entry(Option<EntryKeyRef<'a, T, B>>, Option<EntryValueRef<'a, T, B>>),
1261 Type(std::slice::Iter<'a, Id<T, B>>),
1263 Graph(std::slice::Iter<'a, IndexedObject<T, B>>),
1265 Included(std::slice::Iter<'a, IndexedNode<T, B>>),
1267 Reverse(reverse_properties::Iter<'a, T, B>),
1269 Property(std::slice::Iter<'a, IndexedObject<T, B>>),
1271}
1272
1273impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1274 type Item = super::FragmentRef<'a, T, B>;
1275
1276 fn next(&mut self) -> Option<Self::Item> {
1277 match self {
1278 Self::None => None,
1279 Self::Entry(k, v) => k
1280 .take()
1281 .map(|k| super::FragmentRef::NodeFragment(FragmentRef::Key(k)))
1282 .or_else(|| v.take().map(|v| super::FragmentRef::NodeFragment(FragmentRef::Value(v)))),
1283 Self::Type(l) => l.next_back().map(|t| super::FragmentRef::NodeFragment(FragmentRef::TypeFragment(t))),
1284 Self::Graph(g) => g.next().map(|o| super::FragmentRef::IndexedObject(o)),
1285 Self::Included(i) => i.next().map(|n| super::FragmentRef::IndexedNode(n)),
1286 Self::Reverse(r) => r.next().map(|(_, n)| super::FragmentRef::IndexedNodeList(n)),
1287 Self::Property(o) => o.next().map(|o| super::FragmentRef::IndexedObject(o)),
1288 }
1289 }
1290}
1291
1292impl<T, B> object::Any<T, B> for Node<T, B> {
1293 #[inline(always)]
1294 fn as_ref(&self) -> object::Ref<'_, T, B> {
1295 object::Ref::Node(self)
1296 }
1297}
1298
1299impl<T, B> TryFrom<Object<T, B>> for Node<T, B> {
1300 type Error = Object<T, B>;
1301
1302 #[inline(always)]
1303 fn try_from(obj: Object<T, B>) -> Result<Node<T, B>, Object<T, B>> {
1304 match obj {
1305 Object::Node(node) => Ok(*node),
1306 obj => Err(obj),
1307 }
1308 }
1309}
1310
1311impl<T: Hash, B: Hash> Hash for Node<T, B> {
1312 #[inline]
1313 fn hash<H: Hasher>(&self, h: &mut H) {
1314 self.id.hash(h);
1315 utils::hash_set_opt(self.types.as_ref(), h);
1316 utils::hash_set_opt(self.graph.as_ref(), h);
1317 utils::hash_set_opt(self.included.as_ref(), h);
1318 self.properties.hash(h);
1319 self.reverse_properties.hash(h);
1320 }
1321}
1322
1323pub struct Nodes<'a, T, B>(Option<std::slice::Iter<'a, IndexedNode<T, B>>>);
1325
1326impl<'a, T, B> Nodes<'a, T, B> {
1327 #[inline(always)]
1328 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedNode<T, B>>>) -> Self {
1329 Self(inner)
1330 }
1331}
1332
1333impl<'a, T, B> Iterator for Nodes<'a, T, B> {
1334 type Item = &'a IndexedNode<T, B>;
1335
1336 #[inline(always)]
1337 fn next(&mut self) -> Option<&'a IndexedNode<T, B>> {
1338 match &mut self.0 {
1339 None => None,
1340 Some(it) => it.next(),
1341 }
1342 }
1343}
1344
1345impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Node<T, B> {
1346 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, mut object: jstrict::Object) -> Result<Self, InvalidExpandedJson> {
1347 let id = match object.remove_unique("@id").map_err(InvalidExpandedJson::duplicate_key)? {
1348 Some(entry) => Some(Id::try_from_json_in(vocabulary, entry.value)?),
1349 None => None,
1350 };
1351
1352 let types = match object.remove_unique("@type").map_err(InvalidExpandedJson::duplicate_key)? {
1353 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1354 None => None,
1355 };
1356
1357 let graph = match object.remove_unique("@graph").map_err(InvalidExpandedJson::duplicate_key)? {
1358 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1359 None => None,
1360 };
1361
1362 let included = match object.remove_unique("@included").map_err(InvalidExpandedJson::duplicate_key)? {
1363 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1364 None => None,
1365 };
1366
1367 let reverse_properties = match object.remove_unique("@reverse").map_err(InvalidExpandedJson::duplicate_key)? {
1368 Some(entry) => Some(ReverseProperties::try_from_json_in(vocabulary, entry.value)?),
1369 None => None,
1370 };
1371
1372 let properties = Properties::try_from_json_object_in(vocabulary, object)?;
1373
1374 Ok(Self {
1375 id,
1376 types,
1377 graph,
1378 included,
1379 properties,
1380 reverse_properties,
1381 })
1382 }
1383}
1384
1385impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Node<T, B> {
1386 fn into_json_with(self, vocabulary: &N) -> jstrict::Value {
1387 let mut obj = jstrict::Object::new();
1388
1389 if let Some(id) = self.id {
1390 obj.insert("@id".into(), id.into_with(vocabulary).into_json());
1391 }
1392
1393 if let Some(types) = self.types
1394 && !types.is_empty()
1395 {
1396 let value = types.into_with(vocabulary).into_json();
1397
1398 obj.insert("@type".into(), value);
1399 }
1400
1401 if let Some(graph) = self.graph {
1402 obj.insert("@graph".into(), graph.into_with(vocabulary).into_json());
1403 }
1404
1405 if let Some(included) = self.included {
1406 obj.insert("@included".into(), included.into_with(vocabulary).into_json());
1407 }
1408
1409 if let Some(reverse_properties) = self.reverse_properties {
1410 obj.insert("@reverse".into(), reverse_properties.into_with(vocabulary).into_json());
1411 }
1412
1413 for (prop, objects) in self.properties {
1414 obj.insert(prop.with(vocabulary).to_string().into(), objects.into_json_with(vocabulary));
1415 }
1416
1417 obj.into()
1418 }
1419}