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
86pub struct NodeParts<T = IriBuf, B = BlankIdBuf> {
92 pub id: Option<Id<T, B>>,
94 pub types: Option<Vec<Id<T, B>>>,
96 pub graph: Option<Graph<T, B>>,
98 pub included: Option<Included<T, B>>,
100 pub properties: Properties<T, B>,
102 pub reverse_properties: Option<ReverseProperties<T, B>>,
104}
105
106impl<T, B> Node<T, B> {
107 #[must_use]
112 pub fn into_parts(mut self) -> NodeParts<T, B> {
113 NodeParts {
114 id: self.id.take(),
115 types: self.types.take(),
116 graph: self.graph.take(),
117 included: self.included.take(),
118 properties: std::mem::take(&mut self.properties),
119 reverse_properties: self.reverse_properties.take(),
120 }
121 }
122}
123
124impl<T, B> Default for Node<T, B> {
125 #[inline(always)]
126 fn default() -> Self {
127 Self::new()
128 }
129}
130
131impl<T, B> Node<T, B> {
132 #[inline(always)]
134 #[must_use]
135 pub fn new() -> Self {
136 Self {
137 id: None,
138 types: None,
139 graph: None,
140 included: None,
141 properties: Properties::new(),
142 reverse_properties: None,
143 }
144 }
145
146 #[inline(always)]
148 pub fn with_id(id: Id<T, B>) -> Self {
149 Self {
150 id: Some(id),
151 types: None,
152 graph: None,
153 included: None,
154 properties: Properties::new(),
155 reverse_properties: None,
156 }
157 }
158
159 pub fn new_graph(id: Id<T, B>, graph: Graph<T, B>) -> Self {
161 Self {
162 id: Some(id),
163 types: None,
164 graph: Some(graph),
165 included: None,
166 properties: Properties::new(),
167 reverse_properties: None,
168 }
169 }
170
171 #[inline(always)]
175 pub fn reverse_properties_mut_or_default(&mut self) -> &mut ReverseProperties<T, B> {
176 self.reverse_properties.get_or_insert_with(ReverseProperties::default)
177 }
178
179 #[inline(always)]
183 pub fn included_mut_or_default(&mut self) -> &mut Included<T, B> {
184 self.included.get_or_insert_with(Included::default)
185 }
186
187 pub fn identify_all_with<V: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
194 &mut self,
195 vocabulary: &mut V,
196 generator: &mut G,
197 ) -> Result<(), crate::id::GeneratedIdError>
198 where
199 T: Eq + Hash,
200 B: Eq + Hash,
201 {
202 if self.id.is_none() {
203 self.id = Some(crate::id::generator_next_id(vocabulary, generator)?.into());
204 }
205
206 if let Some(graph) = self.graph_mut() {
207 for o in graph.iter_mut() {
208 o.identify_all_with(vocabulary, generator)?;
209 }
210 }
211
212 if let Some(included) = self.included_mut() {
213 for n in included.iter_mut() {
214 n.identify_all_with(vocabulary, generator)?;
215 }
216 }
217
218 for (_, objects) in self.properties_mut() {
219 for object in objects {
220 object.identify_all_with(vocabulary, generator)?;
221 }
222 }
223
224 if let Some(reverse_properties) = self.reverse_properties_mut() {
225 for (_, nodes) in reverse_properties.iter_mut() {
226 for node in nodes {
227 node.identify_all_with(vocabulary, generator)?;
228 }
229 }
230 }
231
232 Ok(())
233 }
234
235 pub fn identify_all<G: LocalGenerator>(&mut self, generator: &mut G) -> Result<(), crate::id::GeneratedIdError>
241 where
242 T: Eq + Hash,
243 B: Eq + Hash,
244 (): Vocabulary<Iri = T, BlankId = B>,
245 {
246 self.identify_all_with(&mut (), generator)
247 }
248
249 pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
252 for (_, objects) in self.properties_mut() {
253 for object in objects {
254 object.canonicalize_with(buffer);
255 }
256 }
257
258 if let Some(reverse_properties) = self.reverse_properties_mut() {
259 for (_, nodes) in reverse_properties.iter_mut() {
260 for node in nodes {
261 node.canonicalize_with(buffer);
262 }
263 }
264 }
265 }
266
267 pub fn canonicalize(&mut self) {
269 let mut buffer = ryu_js::Buffer::new();
270 self.canonicalize_with(&mut buffer);
271 }
272
273 #[inline(always)]
276 pub fn as_iri(&self) -> Option<&T> {
277 if let Some(id) = &self.id { id.as_iri() } else { None }
278 }
279
280 #[inline(always)]
284 pub fn as_str(&self) -> Option<&str>
285 where
286 T: AsRef<str>,
287 {
288 match self.as_iri() {
289 Some(iri) => Some(iri.as_ref()),
290 None => None,
291 }
292 }
293
294 #[inline(always)]
297 pub fn types(&self) -> &[Id<T, B>] {
298 match self.types.as_ref() {
299 Some(entry) => entry,
300 None => &[],
301 }
302 }
303
304 #[inline(always)]
307 pub fn types_mut(&mut self) -> &mut [Id<T, B>] {
308 match self.types.as_mut() {
309 Some(entry) => entry,
310 None => &mut [],
311 }
312 }
313
314 pub fn types_mut_or_default(&mut self) -> &mut Vec<Id<T, B>> {
317 self.types.get_or_insert_with(Vec::new)
318 }
319
320 pub fn types_mut_or_insert(&mut self, value: Vec<Id<T, B>>) -> &mut Vec<Id<T, B>> {
323 self.types.get_or_insert(value)
324 }
325
326 pub fn types_mut_or_insert_with(&mut self, f: impl FnOnce() -> Vec<Id<T, B>>) -> &mut Vec<Id<T, B>> {
329 self.types.get_or_insert_with(f)
330 }
331
332 #[inline]
334 pub fn has_type<U>(&self, ty: &U) -> bool
335 where
336 Id<T, B>: PartialEq<U>,
337 {
338 for self_ty in self.types() {
339 if self_ty == ty {
340 return true;
341 }
342 }
343
344 false
345 }
346
347 #[inline]
351 pub fn is_empty(&self) -> bool {
352 self.types.is_none() && self.graph.is_none() && self.included.is_none() && self.properties.is_empty() && self.reverse_properties.is_none()
353 }
354
355 #[inline]
360 pub fn is_graph(&self) -> bool {
361 self.graph.is_some() && self.types.is_none() && self.included.is_none() && self.properties.is_empty() && self.reverse_properties.is_none()
362 }
363
364 #[inline(always)]
366 pub fn is_simple_graph(&self) -> bool {
367 self.id.is_none() && self.is_graph()
368 }
369
370 #[inline(always)]
375 pub fn graph(&self) -> Option<&Graph<T, B>> {
376 self.graph.as_ref()
377 }
378
379 #[inline(always)]
382 pub fn graph_mut(&mut self) -> Option<&mut Graph<T, B>> {
383 self.graph.as_mut()
384 }
385
386 #[inline(always)]
390 pub fn graph_entry(&self) -> Option<&Graph<T, B>> {
391 self.graph.as_ref()
392 }
393
394 #[inline(always)]
399 pub fn graph_entry_mut(&mut self) -> Option<&mut Graph<T, B>> {
400 self.graph.as_mut()
401 }
402
403 #[inline(always)]
405 pub fn set_graph_entry(&mut self, graph: Option<Graph<T, B>>) {
406 self.graph = graph;
407 }
408
409 #[inline(always)]
413 pub fn included_entry(&self) -> Option<&Included<T, B>> {
414 self.included.as_ref()
415 }
416
417 #[inline(always)]
421 pub fn included_entry_mut(&mut self) -> Option<&mut Included<T, B>> {
422 self.included.as_mut()
423 }
424
425 pub fn included(&self) -> Option<&Included<T, B>> {
427 self.included.as_ref()
428 }
429
430 pub fn included_mut(&mut self) -> Option<&mut Included<T, B>> {
432 self.included.as_mut()
433 }
434
435 #[inline(always)]
438 pub fn set_included(&mut self, included: Option<Included<T, B>>) {
439 self.included = included;
440 }
441
442 #[inline(always)]
444 pub fn properties(&self) -> &Properties<T, B> {
445 &self.properties
446 }
447
448 #[inline(always)]
450 pub fn properties_mut(&mut self) -> &mut Properties<T, B> {
451 &mut self.properties
452 }
453
454 #[inline(always)]
457 pub fn reverse_properties(&self) -> Option<&ReverseProperties<T, B>> {
458 self.reverse_properties.as_ref()
459 }
460
461 #[inline(always)]
464 pub fn reverse_properties_entry(&self) -> Option<&ReverseProperties<T, B>> {
465 self.reverse_properties.as_ref()
466 }
467
468 #[inline(always)]
471 pub fn reverse_properties_mut(&mut self) -> Option<&mut ReverseProperties<T, B>> {
472 self.reverse_properties.as_mut()
473 }
474
475 pub fn set_reverse_properties(&mut self, reverse_properties: Option<ReverseProperties<T, B>>) {
477 self.reverse_properties = reverse_properties;
478 }
479
480 #[inline]
485 pub fn is_unnamed_graph(&self) -> bool {
486 self.graph.is_some()
487 && self.id.is_none()
488 && self.types.is_none()
489 && self.included.is_none()
490 && self.properties.is_empty()
491 && self.reverse_properties.is_none()
492 }
493
494 #[inline(always)]
503 pub fn into_unnamed_graph(self: Box<Self>) -> Result<Graph<T, B>, Box<Self>> {
504 if self.is_unnamed_graph() {
505 Ok((*self).into_parts().graph.unwrap_or_default())
507 } else {
508 Err(self)
509 }
510 }
511
512 pub fn traverse(&self) -> Traverse<'_, T, B> {
515 Traverse::new(Some(super::FragmentRef::Node(self)))
516 }
517
518 #[inline(always)]
519 pub fn count(&self, f: impl FnMut(&super::FragmentRef<T, B>) -> bool) -> usize {
521 self.traverse().filter(f).count()
522 }
523
524 pub fn entries(&self) -> Entries<'_, T, B> {
527 Entries {
528 id: self.id.as_ref(),
529 type_: self.types.as_deref(),
530 graph: self.graph.as_ref(),
531 included: self.included.as_ref(),
532 reverse: self.reverse_properties.as_ref(),
533 properties: self.properties.iter(),
534 }
535 }
536
537 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>
540 where
541 U: Eq + Hash,
542 C: Eq + Hash,
543 {
544 self.map_ids_with(&mut map_iri, &mut map_id)
545 }
546
547 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>
548 where
549 U: Eq + Hash,
550 C: Eq + Hash,
551 {
552 let NodeParts {
553 id,
554 types,
555 graph,
556 included,
557 properties,
558 reverse_properties,
559 } = self.into_parts();
560 Node {
561 id: id.map(&mut *map_id),
562 types: types.map(|t| t.into_iter().map(&mut *map_id).collect()),
563 graph: graph.map(|g| g.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect()),
564 included: included.map(|i| i.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect()),
565 properties: properties
566 .into_iter()
567 .map(|(id, values)| {
568 (
569 map_id(id),
570 values.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect::<Vec<_>>(),
571 )
572 })
573 .collect(),
574 reverse_properties: reverse_properties.map(|r| {
575 r.into_iter()
576 .map(|(id, values)| {
577 (
578 map_id(id),
579 values.into_iter().map(|o| o.map_inner(|o| o.map_ids_with(map_iri, map_id))).collect::<Vec<_>>(),
580 )
581 })
582 .collect()
583 }),
584 }
585 }
586}
587
588impl<T: Eq + Hash, B: Eq + Hash> Node<T, B> {
589 #[inline(always)]
603 pub fn has_key(&self, key: &Term<T, B>) -> bool {
604 match key {
605 Term::Keyword(Keyword::Id) => self.id.is_some(),
606 Term::Keyword(Keyword::Type) => self.types.is_some(),
607 Term::Keyword(Keyword::Graph) => self.graph.is_some(),
608 Term::Keyword(Keyword::Included) => self.included.is_some(),
609 Term::Keyword(Keyword::Reverse) => self.reverse_properties.is_some(),
610 Term::Id(prop) => self.properties.contains(prop),
611 _ => false,
612 }
613 }
614
615 #[inline(always)]
618 pub fn get<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(&self, prop: &Q) -> Objects<'_, T, B>
619 where
620 T: 'a,
621 {
622 self.properties.get(prop)
623 }
624
625 #[inline(always)]
631 pub fn get_any<'a, Q: ?Sized + Hash + indexmap::Equivalent<Id<T, B>>>(&self, prop: &Q) -> Option<&IndexedObject<T, B>>
632 where
633 T: 'a,
634 {
635 self.properties.get_any(prop)
636 }
637
638 #[inline(always)]
640 pub fn insert(&mut self, prop: Id<T, B>, value: IndexedObject<T, B>) {
641 self.properties.insert(prop, value);
642 }
643
644 #[inline(always)]
650 pub fn insert_all<Objects: Iterator<Item = IndexedObject<T, B>>>(&mut self, prop: Id<T, B>, values: Objects) {
651 self.properties.insert_all(prop, values);
652 }
653
654 pub fn reverse_properties_or_insert(&mut self, props: ReverseProperties<T, B>) -> &mut ReverseProperties<T, B> {
657 self.reverse_properties.get_or_insert(props)
658 }
659
660 pub fn reverse_properties_or_default(&mut self) -> &mut ReverseProperties<T, B> {
663 self.reverse_properties.get_or_insert_with(ReverseProperties::default)
664 }
665
666 pub fn reverse_properties_or_insert_with(&mut self, f: impl FnOnce() -> ReverseProperties<T, B>) -> &mut ReverseProperties<T, B> {
669 self.reverse_properties.get_or_insert_with(f)
670 }
671
672 pub fn equivalent(&self, other: &Self) -> bool {
678 if self.id.is_some() && other.id.is_some() { self == other } else { false }
679 }
680}
681
682impl<T, B> Relabel<T, B> for Node<T, B> {
683 fn relabel_with<N: VocabularyMut<Iri = T, BlankId = B>, G: LocalGenerator>(
684 &mut self,
685 vocabulary: &mut N,
686 generator: &mut G,
687 relabeling: &mut HashMap<B, ValidId<T, B>>,
688 ) -> Result<(), crate::id::GeneratedIdError>
689 where
690 T: Clone + Eq + Hash,
691 B: Clone + Eq + Hash,
692 {
693 self.id = match self.id.take() {
694 Some(Id::Valid(ValidId::Blank(b))) => {
695 let value = match relabeling.entry(b) {
696 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
697 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
698 };
699 Some(value.into())
700 }
701 None => {
702 let value = crate::id::generator_next_id(vocabulary, generator)?;
703 Some(value.into())
704 }
705 id => id,
706 };
707
708 for ty in self.types_mut() {
709 if let Some(b) = ty.as_blank().cloned() {
710 let value = match relabeling.entry(b) {
711 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
712 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
713 };
714 *ty = value.into();
715 }
716 }
717
718 if let Some(graph) = self.graph_mut() {
719 for o in graph.iter_mut() {
720 o.relabel_with(vocabulary, generator, relabeling)?;
721 }
722 }
723
724 if let Some(included) = self.included_mut() {
725 for n in included.iter_mut() {
726 n.relabel_with(vocabulary, generator, relabeling)?;
727 }
728 }
729
730 if !self.properties.is_empty() {
736 let properties = std::mem::take(&mut self.properties);
737 for (property, mut objects) in properties {
738 let property = match property {
739 Id::Valid(ValidId::Blank(b)) => {
740 let value = match relabeling.entry(b) {
741 hashbrown::hash_map::Entry::Occupied(o) => o.get().clone(),
742 hashbrown::hash_map::Entry::Vacant(v) => v.insert(crate::id::generator_next_id(vocabulary, generator)?).clone(),
743 };
744 value.into()
745 }
746 property => property,
747 };
748
749 for object in &mut objects {
750 object.relabel_with(vocabulary, generator, relabeling)?;
751 }
752
753 self.properties.set(property, objects);
754 }
755 }
756
757 if let Some(reverse_properties) = self.reverse_properties_mut() {
758 for (_, nodes) in reverse_properties.iter_mut() {
759 for node in nodes {
760 node.relabel_with(vocabulary, generator, relabeling)?;
761 }
762 }
763 }
764
765 Ok(())
766 }
767}
768
769impl<T: Eq + Hash, B: Eq + Hash> PartialEq for Node<T, B> {
770 fn eq(&self, other: &Self) -> bool {
771 self.id.eq(&other.id)
775 && multiset::compare_unordered_opt(self.types.as_deref(), other.types.as_deref())
776 && multiset::compare_unordered_opt(self.graph.as_deref(), other.graph.as_deref())
777 && multiset::compare_unordered_opt(self.included.as_deref(), other.included.as_deref())
778 && self.properties.eq(&other.properties)
779 && self.reverse_properties.eq(&other.reverse_properties)
780 }
781}
782
783impl<T: Eq + Hash, B: Eq + Hash> Eq for Node<T, B> {}
784
785impl<T, B> Indexed<Node<T, B>> {
786 pub fn entries(&self) -> IndexedEntries<'_, T, B> {
789 IndexedEntries {
790 index: self.index(),
791 inner: self.inner().entries(),
792 }
793 }
794}
795
796impl<T: Eq + Hash, B: Eq + Hash> Indexed<Node<T, B>> {
797 pub fn equivalent(&self, other: &Self) -> bool {
800 self.index() == other.index() && self.inner().equivalent(other.inner())
801 }
802}
803
804#[derive(PartialEq, Eq)]
810#[derive_where(Clone, Copy)]
811pub enum EntryKeyRef<'a, T, B> {
813 Id,
815 Type,
817 Graph,
819 Included,
821 Reverse,
823 Property(&'a Id<T, B>),
825}
826
827impl<'a, T, B> EntryKeyRef<'a, T, B> {
828 #[must_use]
830 pub fn into_keyword(self) -> Option<Keyword> {
831 match self {
832 Self::Id => Some(Keyword::Id),
833 Self::Type => Some(Keyword::Type),
834 Self::Graph => Some(Keyword::Graph),
835 Self::Included => Some(Keyword::Included),
836 Self::Reverse => Some(Keyword::Reverse),
837 Self::Property(_) => None,
838 }
839 }
840
841 #[must_use]
843 pub fn as_keyword(&self) -> Option<Keyword> {
844 self.into_keyword()
845 }
846
847 #[must_use]
849 pub fn into_str(self) -> &'a str
850 where
851 T: AsRef<str>,
852 B: AsRef<str>,
853 {
854 match self {
855 Self::Id => "@id",
856 Self::Type => "@type",
857 Self::Graph => "@graph",
858 Self::Included => "@included",
859 Self::Reverse => "@reverse",
860 Self::Property(p) => p.as_str(),
861 }
862 }
863
864 #[must_use]
866 pub fn as_str(&self) -> &'a str
867 where
868 T: AsRef<str>,
869 B: AsRef<str>,
870 {
871 self.into_str()
872 }
873}
874
875impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for EntryKeyRef<'a, T, B> {
876 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
877 match self {
878 EntryKeyRef::Id => "@id",
879 EntryKeyRef::Type => "@type",
880 EntryKeyRef::Graph => "@graph",
881 EntryKeyRef::Included => "@included",
882 EntryKeyRef::Reverse => "@reverse",
883 EntryKeyRef::Property(p) => p.with(vocabulary).as_str(),
884 }
885 }
886}
887
888#[derive_where(Clone, Copy)]
889pub enum EntryValueRef<'a, T, B> {
891 Id(&'a Id<T, B>),
893 Type(&'a [Id<T, B>]),
895 Graph(&'a Graph<T, B>),
897 Included(&'a Included<T, B>),
899 Reverse(&'a ReverseProperties<T, B>),
901 Property(&'a [IndexedObject<T, B>]),
903}
904
905impl<'a, T, B> EntryValueRef<'a, T, B> {
906 #[must_use]
908 pub fn is_json_array(&self) -> bool {
909 matches!(self, Self::Type(_) | Self::Graph(_) | Self::Included(_) | Self::Property(_))
910 }
911
912 #[must_use]
914 pub fn is_json_object(&self) -> bool {
915 matches!(self, Self::Reverse(_))
916 }
917
918 fn sub_fragments(&self) -> SubFragments<'a, T, B> {
919 match self {
920 Self::Type(l) => SubFragments::Type(l.iter()),
921 Self::Graph(g) => SubFragments::Graph(g.iter()),
922 Self::Included(i) => SubFragments::Included(i.iter()),
923 Self::Reverse(r) => SubFragments::Reverse(r.iter()),
924 Self::Property(p) => SubFragments::Property(p.iter()),
925 Self::Id(_) => SubFragments::None,
926 }
927 }
928}
929
930#[derive_where(Clone, Copy)]
931pub enum EntryRef<'a, T, B> {
933 Id(&'a Id<T, B>),
935 Type(&'a [Id<T, B>]),
937 Graph(&'a Graph<T, B>),
939 Included(&'a Included<T, B>),
941 Reverse(&'a ReverseProperties<T, B>),
943 Property(&'a Id<T, B>, &'a [IndexedObject<T, B>]),
945}
946
947impl<'a, T, B> EntryRef<'a, T, B> {
948 #[must_use]
950 pub fn into_key(self) -> EntryKeyRef<'a, T, B> {
951 match self {
952 Self::Id(_) => EntryKeyRef::Id,
953 Self::Type(_) => EntryKeyRef::Type,
954 Self::Graph(_) => EntryKeyRef::Graph,
955 Self::Included(_) => EntryKeyRef::Included,
956 Self::Reverse(_) => EntryKeyRef::Reverse,
957 Self::Property(k, _) => EntryKeyRef::Property(k),
958 }
959 }
960
961 #[must_use]
963 pub fn key(&self) -> EntryKeyRef<'a, T, B> {
964 self.into_key()
965 }
966
967 #[must_use]
969 pub fn into_value(self) -> EntryValueRef<'a, T, B> {
970 match self {
971 Self::Id(v) => EntryValueRef::Id(v),
972 Self::Type(v) => EntryValueRef::Type(v),
973 Self::Graph(v) => EntryValueRef::Graph(v),
974 Self::Included(v) => EntryValueRef::Included(v),
975 Self::Reverse(v) => EntryValueRef::Reverse(v),
976 Self::Property(_, v) => EntryValueRef::Property(v),
977 }
978 }
979
980 #[must_use]
982 pub fn value(&self) -> EntryValueRef<'a, T, B> {
983 self.into_value()
984 }
985
986 #[must_use]
988 pub fn into_key_value(self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
989 match self {
990 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(v)),
991 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
992 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(v)),
993 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(v)),
994 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(v)),
995 Self::Property(k, v) => (EntryKeyRef::Property(k), EntryValueRef::Property(v)),
996 }
997 }
998
999 #[must_use]
1001 pub fn as_key_value(&self) -> (EntryKeyRef<'a, T, B>, EntryValueRef<'a, T, B>) {
1002 match self {
1003 Self::Id(v) => (EntryKeyRef::Id, EntryValueRef::Id(*v)),
1004 Self::Type(v) => (EntryKeyRef::Type, EntryValueRef::Type(v)),
1005 Self::Graph(v) => (EntryKeyRef::Graph, EntryValueRef::Graph(*v)),
1006 Self::Included(v) => (EntryKeyRef::Included, EntryValueRef::Included(*v)),
1007 Self::Reverse(v) => (EntryKeyRef::Reverse, EntryValueRef::Reverse(*v)),
1008 Self::Property(k, v) => (EntryKeyRef::Property(*k), EntryValueRef::Property(v)),
1009 }
1010 }
1011}
1012
1013#[derive_where(Clone)]
1014pub struct Entries<'a, T, B> {
1016 id: Option<&'a Id<T, B>>,
1017 type_: Option<&'a [Id<T, B>]>,
1018 graph: Option<&'a Graph<T, B>>,
1019 included: Option<&'a Included<T, B>>,
1020 reverse: Option<&'a ReverseProperties<T, B>>,
1021 properties: properties::Iter<'a, T, B>,
1022}
1023
1024impl<'a, T, B> Iterator for Entries<'a, T, B> {
1025 type Item = EntryRef<'a, T, B>;
1026
1027 fn size_hint(&self) -> (usize, Option<usize>) {
1028 let mut len = self.properties.len();
1029
1030 if self.id.is_some() {
1031 len += 1;
1032 }
1033
1034 if self.type_.is_some() {
1035 len += 1;
1036 }
1037
1038 if self.graph.is_some() {
1039 len += 1;
1040 }
1041
1042 if self.included.is_some() {
1043 len += 1;
1044 }
1045
1046 if self.reverse.is_some() {
1047 len += 1;
1048 }
1049
1050 (len, Some(len))
1051 }
1052
1053 fn next(&mut self) -> Option<Self::Item> {
1054 self.id.take().map(EntryRef::Id).or_else(|| {
1055 self.type_.take().map(EntryRef::Type).or_else(|| {
1056 self.graph.take().map(EntryRef::Graph).or_else(|| {
1057 self.included.take().map(EntryRef::Included).or_else(|| {
1058 self.reverse
1059 .take()
1060 .map(EntryRef::Reverse)
1061 .or_else(|| self.properties.next().map(|(k, v)| EntryRef::Property(k, v)))
1062 })
1063 })
1064 })
1065 })
1066 }
1067}
1068
1069impl<T, B> ExactSizeIterator for Entries<'_, T, B> {}
1070
1071#[derive_where(Clone)]
1072pub struct IndexedEntries<'a, T, B> {
1074 index: Option<&'a str>,
1075 inner: Entries<'a, T, B>,
1076}
1077
1078impl<'a, T, B> Iterator for IndexedEntries<'a, T, B> {
1079 type Item = IndexedEntryRef<'a, T, B>;
1080
1081 fn size_hint(&self) -> (usize, Option<usize>) {
1082 let len = self.inner.len() + usize::from(self.index.is_some());
1083 (len, Some(len))
1084 }
1085
1086 fn next(&mut self) -> Option<Self::Item> {
1087 self.index
1088 .take()
1089 .map(IndexedEntryRef::Index)
1090 .or_else(|| self.inner.next().map(IndexedEntryRef::Node))
1091 }
1092}
1093
1094impl<T, B> ExactSizeIterator for IndexedEntries<'_, T, B> {}
1095
1096#[derive(PartialEq, Eq)]
1097#[derive_where(Clone, Copy)]
1098pub enum IndexedEntryKeyRef<'a, T, B> {
1100 Index,
1102 Node(EntryKeyRef<'a, T, B>),
1104}
1105
1106impl<'a, T, B> IndexedEntryKeyRef<'a, T, B> {
1107 #[must_use]
1109 pub fn into_keyword(self) -> Option<Keyword> {
1110 match self {
1111 Self::Index => Some(Keyword::Index),
1112 Self::Node(e) => e.into_keyword(),
1113 }
1114 }
1115
1116 #[must_use]
1118 pub fn as_keyword(&self) -> Option<Keyword> {
1119 self.into_keyword()
1120 }
1121
1122 #[must_use]
1124 pub fn into_str(self) -> &'a str
1125 where
1126 T: AsRef<str>,
1127 B: AsRef<str>,
1128 {
1129 match self {
1130 Self::Index => "@index",
1131 Self::Node(e) => e.into_str(),
1132 }
1133 }
1134
1135 #[must_use]
1137 pub fn as_str(&self) -> &'a str
1138 where
1139 T: AsRef<str>,
1140 B: AsRef<str>,
1141 {
1142 self.into_str()
1143 }
1144}
1145
1146impl<'a, T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoRefWithContext<'a, str, N> for IndexedEntryKeyRef<'a, T, B> {
1147 fn into_ref_with(self, vocabulary: &'a N) -> &'a str {
1148 match self {
1149 IndexedEntryKeyRef::Index => "@index",
1150 IndexedEntryKeyRef::Node(e) => e.into_with(vocabulary).into_str(),
1151 }
1152 }
1153}
1154
1155#[derive_where(Clone, Copy)]
1156pub enum IndexedEntryValueRef<'a, T, B> {
1158 Index(&'a str),
1160 Node(EntryValueRef<'a, T, B>),
1162}
1163
1164#[derive_where(Clone, Copy)]
1165pub enum IndexedEntryRef<'a, T, B> {
1167 Index(&'a str),
1169 Node(EntryRef<'a, T, B>),
1171}
1172
1173impl<'a, T, B> IndexedEntryRef<'a, T, B> {
1174 #[must_use]
1176 pub fn into_key(self) -> IndexedEntryKeyRef<'a, T, B> {
1177 match self {
1178 Self::Index(_) => IndexedEntryKeyRef::Index,
1179 Self::Node(e) => IndexedEntryKeyRef::Node(e.key()),
1180 }
1181 }
1182
1183 #[must_use]
1185 pub fn key(&self) -> IndexedEntryKeyRef<'a, T, B> {
1186 self.into_key()
1187 }
1188
1189 #[must_use]
1191 pub fn into_value(self) -> IndexedEntryValueRef<'a, T, B> {
1192 match self {
1193 Self::Index(v) => IndexedEntryValueRef::Index(v),
1194 Self::Node(e) => IndexedEntryValueRef::Node(e.value()),
1195 }
1196 }
1197
1198 #[must_use]
1200 pub fn value(&self) -> IndexedEntryValueRef<'a, T, B> {
1201 self.into_value()
1202 }
1203
1204 #[must_use]
1206 pub fn into_key_value(self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1207 match self {
1208 Self::Index(v) => (IndexedEntryKeyRef::Index, IndexedEntryValueRef::Index(v)),
1209 Self::Node(e) => {
1210 let (k, v) = e.into_key_value();
1211 (IndexedEntryKeyRef::Node(k), IndexedEntryValueRef::Node(v))
1212 }
1213 }
1214 }
1215
1216 #[must_use]
1218 pub fn as_key_value(&self) -> (IndexedEntryKeyRef<'a, T, B>, IndexedEntryValueRef<'a, T, B>) {
1219 self.into_key_value()
1220 }
1221}
1222
1223pub enum FragmentRef<'a, T, B> {
1225 Entry(EntryRef<'a, T, B>),
1227
1228 Key(EntryKeyRef<'a, T, B>),
1230
1231 Value(EntryValueRef<'a, T, B>),
1233
1234 TypeFragment(&'a Id<T, B>),
1236}
1237
1238impl<'a, T, B> FragmentRef<'a, T, B> {
1239 #[must_use]
1241 pub fn into_id(self) -> Option<&'a Id<T, B>> {
1242 match self {
1243 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1244 Self::Value(EntryValueRef::Id(id)) => Some(id),
1245 Self::TypeFragment(ty) => Some(ty),
1246 _ => None,
1247 }
1248 }
1249
1250 #[must_use]
1252 pub fn as_id(&self) -> Option<&'a Id<T, B>> {
1253 match self {
1254 Self::Key(EntryKeyRef::Property(id)) => Some(id),
1255 Self::Value(EntryValueRef::Id(id)) => Some(id),
1256 Self::TypeFragment(ty) => Some(ty),
1257 _ => None,
1258 }
1259 }
1260
1261 #[must_use]
1263 pub fn is_json_array(&self) -> bool {
1264 match self {
1265 Self::Value(v) => v.is_json_array(),
1266 _ => false,
1267 }
1268 }
1269
1270 #[must_use]
1272 pub fn is_json_object(&self) -> bool {
1273 match self {
1274 Self::Value(v) => v.is_json_object(),
1275 _ => false,
1276 }
1277 }
1278
1279 #[must_use]
1281 pub fn sub_fragments(&self) -> SubFragments<'a, T, B> {
1282 match self {
1283 Self::Entry(e) => SubFragments::Entry(Some(e.key()), Some(e.value())),
1284 Self::Value(v) => v.sub_fragments(),
1285 _ => SubFragments::None,
1286 }
1287 }
1288}
1289
1290pub enum SubFragments<'a, T, B> {
1292 None,
1294 Entry(Option<EntryKeyRef<'a, T, B>>, Option<EntryValueRef<'a, T, B>>),
1296 Type(std::slice::Iter<'a, Id<T, B>>),
1298 Graph(std::slice::Iter<'a, IndexedObject<T, B>>),
1300 Included(std::slice::Iter<'a, IndexedNode<T, B>>),
1302 Reverse(reverse_properties::Iter<'a, T, B>),
1304 Property(std::slice::Iter<'a, IndexedObject<T, B>>),
1306}
1307
1308impl<'a, T, B> Iterator for SubFragments<'a, T, B> {
1309 type Item = super::FragmentRef<'a, T, B>;
1310
1311 fn next(&mut self) -> Option<Self::Item> {
1312 match self {
1313 Self::None => None,
1314 Self::Entry(k, v) => k
1315 .take()
1316 .map(|k| super::FragmentRef::NodeFragment(FragmentRef::Key(k)))
1317 .or_else(|| v.take().map(|v| super::FragmentRef::NodeFragment(FragmentRef::Value(v)))),
1318 Self::Type(l) => l.next_back().map(|t| super::FragmentRef::NodeFragment(FragmentRef::TypeFragment(t))),
1319 Self::Graph(g) => g.next().map(|o| super::FragmentRef::IndexedObject(o)),
1320 Self::Included(i) => i.next().map(|n| super::FragmentRef::IndexedNode(n)),
1321 Self::Reverse(r) => r.next().map(|(_, n)| super::FragmentRef::IndexedNodeList(n)),
1322 Self::Property(o) => o.next().map(|o| super::FragmentRef::IndexedObject(o)),
1323 }
1324 }
1325}
1326
1327impl<T, B> object::Any<T, B> for Node<T, B> {
1328 #[inline(always)]
1329 fn as_ref(&self) -> object::Ref<'_, T, B> {
1330 object::Ref::Node(self)
1331 }
1332}
1333
1334impl<T, B> TryFrom<Object<T, B>> for Node<T, B> {
1335 type Error = Object<T, B>;
1336
1337 #[inline(always)]
1338 fn try_from(obj: Object<T, B>) -> Result<Node<T, B>, Object<T, B>> {
1339 match obj {
1340 Object::Node(node) => Ok(*node),
1341 obj => Err(obj),
1342 }
1343 }
1344}
1345
1346impl<T: Hash, B: Hash> Hash for Node<T, B> {
1347 #[inline]
1348 fn hash<H: Hasher>(&self, h: &mut H) {
1349 self.id.hash(h);
1350 utils::hash_set_opt(self.types.as_ref(), h);
1351 utils::hash_set_opt(self.graph.as_ref(), h);
1352 utils::hash_set_opt(self.included.as_ref(), h);
1353 self.properties.hash(h);
1354 self.reverse_properties.hash(h);
1355 }
1356}
1357
1358pub struct Nodes<'a, T, B>(Option<std::slice::Iter<'a, IndexedNode<T, B>>>);
1360
1361impl<'a, T, B> Nodes<'a, T, B> {
1362 #[inline(always)]
1363 pub(crate) fn new(inner: Option<std::slice::Iter<'a, IndexedNode<T, B>>>) -> Self {
1364 Self(inner)
1365 }
1366}
1367
1368impl<'a, T, B> Iterator for Nodes<'a, T, B> {
1369 type Item = &'a IndexedNode<T, B>;
1370
1371 #[inline(always)]
1372 fn next(&mut self) -> Option<&'a IndexedNode<T, B>> {
1373 match &mut self.0 {
1374 None => None,
1375 Some(it) => it.next(),
1376 }
1377 }
1378}
1379
1380impl<T: Eq + Hash, B: Eq + Hash> TryFromJsonObject<T, B> for Node<T, B> {
1381 fn try_from_json_object_in(vocabulary: &mut impl VocabularyMut<Iri = T, BlankId = B>, mut object: jstrict::Object) -> Result<Self, InvalidExpandedJson> {
1382 let id = match object.remove_unique("@id").map_err(InvalidExpandedJson::duplicate_key)? {
1383 Some(entry) => Some(Id::try_from_json_in(vocabulary, entry.value)?),
1384 None => None,
1385 };
1386
1387 let types = match object.remove_unique("@type").map_err(InvalidExpandedJson::duplicate_key)? {
1388 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1389 None => None,
1390 };
1391
1392 let graph = match object.remove_unique("@graph").map_err(InvalidExpandedJson::duplicate_key)? {
1393 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1394 None => None,
1395 };
1396
1397 let included = match object.remove_unique("@included").map_err(InvalidExpandedJson::duplicate_key)? {
1398 Some(entry) => Some(Vec::try_from_json_in(vocabulary, entry.value)?),
1399 None => None,
1400 };
1401
1402 let reverse_properties = match object.remove_unique("@reverse").map_err(InvalidExpandedJson::duplicate_key)? {
1403 Some(entry) => Some(ReverseProperties::try_from_json_in(vocabulary, entry.value)?),
1404 None => None,
1405 };
1406
1407 let properties = Properties::try_from_json_object_in(vocabulary, object)?;
1408
1409 Ok(Self {
1410 id,
1411 types,
1412 graph,
1413 included,
1414 properties,
1415 reverse_properties,
1416 })
1417 }
1418}
1419
1420impl<T, B, N: Vocabulary<Iri = T, BlankId = B>> IntoJsonWithContext<N> for Node<T, B> {
1421 fn into_json_with(self, vocabulary: &N) -> jstrict::Value {
1422 let NodeParts {
1423 id,
1424 types,
1425 graph,
1426 included,
1427 properties,
1428 reverse_properties,
1429 } = self.into_parts();
1430 let mut obj = jstrict::Object::new();
1431
1432 if let Some(id) = id {
1433 obj.insert("@id".into(), id.into_with(vocabulary).into_json());
1434 }
1435
1436 if let Some(types) = types
1437 && !types.is_empty()
1438 {
1439 let value = types.into_with(vocabulary).into_json();
1440
1441 obj.insert("@type".into(), value);
1442 }
1443
1444 if let Some(graph) = graph {
1445 obj.insert("@graph".into(), graph.into_with(vocabulary).into_json());
1446 }
1447
1448 if let Some(included) = included {
1449 obj.insert("@included".into(), included.into_with(vocabulary).into_json());
1450 }
1451
1452 if let Some(reverse_properties) = reverse_properties {
1453 obj.insert("@reverse".into(), reverse_properties.into_with(vocabulary).into_json());
1454 }
1455
1456 for (prop, objects) in properties {
1457 obj.insert(prop.with(vocabulary).to_string().into(), objects.into_json_with(vocabulary));
1458 }
1459
1460 obj.into()
1461 }
1462}