jsonld_serialization/expanded/
node.rs1use iri_rs::Iri;
2use jsonld_core::{Indexed, Node, Object, object::node::Multiset, rdf::RDF_TYPE};
3use ld_core::{CowRdfTerm, LinkedDataResource, OwnedRdfTerm};
4use rdfx::{
5 Interpretation,
6 interpretation::{ReverseInterpretation, ReverseLocalInterpretation},
7 vocabulary::{IriVocabulary, Vocabulary},
8};
9use std::hash::Hash;
10
11use crate::Error;
12
13use super::{
14 graph::SerializeGraph,
15 property::{SerializeProperty, SerializeReverseProperty},
16};
17
18pub fn serialize_node_with<I, V, T>(vocabulary: &mut V, interpretation: &mut I, value: &T) -> Result<Node<V::Iri, V::BlankId>, Error>
25where
26 V: Vocabulary + rdfx::vocabulary::VocabularyMut,
27 V::Iri: Clone + Eq + Hash,
28 V::BlankId: Clone + Eq + Hash,
29 I: ReverseInterpretation + ReverseLocalInterpretation,
30 T: ?Sized + LinkedDataResource<I> + ld_core::LinkedDataSubject<I>,
31{
32 let id = match value.lexical_representation(interpretation).map(CowRdfTerm::into_owned) {
33 Some(OwnedRdfTerm::Literal(_)) => return Err(Error::InvalidNode),
34 Some(OwnedRdfTerm::Iri(iri)) => Some(jsonld_core::Id::Valid(jsonld_core::ValidId::Iri(vocabulary.insert_owned(iri)))),
35 Some(OwnedRdfTerm::BlankId(b)) => Some(jsonld_core::Id::Valid(jsonld_core::ValidId::Blank(vocabulary.insert_owned_blank_id(b)))),
36 None => None,
37 };
38
39 let serializer = SerializeNode::new(vocabulary, interpretation, id);
40
41 value.visit_subject(serializer)
42}
43
44pub struct SerializeNode<'a, I, V: Vocabulary> {
45 vocabulary: &'a mut V,
46 interpretation: &'a mut I,
47 result: Node<V::Iri, V::BlankId>,
48}
49
50impl<'a, I, V: Vocabulary> SerializeNode<'a, I, V> {
51 pub fn new(vocabulary: &'a mut V, interpretation: &'a mut I, id: Option<jsonld_core::Id<V::Iri, V::BlankId>>) -> Self {
52 let result = match id {
53 Some(id) => Node::with_id(id),
54 None => Node::new(),
55 };
56
57 Self {
58 vocabulary,
59 interpretation,
60 result,
61 }
62 }
63}
64
65impl<I: Interpretation, V: Vocabulary> ld_core::SubjectVisitor<I> for SerializeNode<'_, I, V>
66where
67 V: rdfx::vocabulary::VocabularyMut,
68 V::Iri: Clone + Eq + Hash,
69 V::BlankId: Clone + Eq + Hash,
70 I: ReverseInterpretation + ReverseLocalInterpretation,
71{
72 type Ok = Node<V::Iri, V::BlankId>;
73 type Error = Error;
74
75 fn predicate<L, T>(&mut self, predicate: &L, value: &T) -> Result<(), Self::Error>
76 where
77 L: ?Sized + LinkedDataResource<I>,
78 T: ?Sized + ld_core::LinkedDataPredicateObjects<I>,
79 {
80 let prop = match predicate.lexical_representation(self.interpretation).map(CowRdfTerm::into_owned) {
81 Some(OwnedRdfTerm::Iri(iri)) => jsonld_core::Id::Valid(jsonld_core::ValidId::Iri(self.vocabulary.insert_owned(iri))),
82 Some(OwnedRdfTerm::BlankId(b)) => jsonld_core::Id::Valid(jsonld_core::ValidId::Blank(self.vocabulary.insert_owned_blank_id(b))),
83 _ => return Err(Error::InvalidPredicate),
84 };
85
86 let serializer = SerializeProperty::new(self.vocabulary, self.interpretation);
87
88 let objects = value.visit_objects(serializer)?;
89
90 if is_iri(self.vocabulary, &prop, RDF_TYPE) {
91 let mut non_iri_objects = Multiset::new();
92
93 for obj in objects {
94 match into_type_value(obj) {
95 Ok(ty) => self.result.types_mut_or_default().push(ty),
96 Err(obj) => {
97 non_iri_objects.insert(obj);
98 }
99 }
100 }
101
102 if !non_iri_objects.is_empty() {
103 self.result.properties_mut().set(prop, non_iri_objects);
104 }
105 } else {
106 self.result.properties_mut().set(prop, objects);
107 }
108
109 Ok(())
110 }
111
112 fn reverse_predicate<L, T>(&mut self, predicate: &L, value: &T) -> Result<(), Self::Error>
113 where
114 L: ?Sized + LinkedDataResource<I>,
115 T: ?Sized + ld_core::LinkedDataPredicateObjects<I>,
116 {
117 let prop = match predicate.lexical_representation(self.interpretation).map(CowRdfTerm::into_owned) {
118 Some(OwnedRdfTerm::Iri(iri)) => jsonld_core::Id::Valid(jsonld_core::ValidId::Iri(self.vocabulary.insert_owned(iri))),
119 Some(OwnedRdfTerm::BlankId(b)) => jsonld_core::Id::Valid(jsonld_core::ValidId::Blank(self.vocabulary.insert_owned_blank_id(b))),
120 _ => return Err(Error::InvalidPredicate),
121 };
122
123 let serializer = SerializeReverseProperty::new(self.vocabulary, self.interpretation);
124
125 let objects = value.visit_objects(serializer)?;
126 self.result.reverse_properties_mut_or_default().set(prop, objects);
127
128 Ok(())
129 }
130
131 fn include<T>(&mut self, value: &T) -> Result<(), Self::Error>
132 where
133 T: ?Sized + LinkedDataResource<I> + ld_core::LinkedDataSubject<I>,
134 {
135 let node = serialize_node_with(self.vocabulary, self.interpretation, value)?;
136
137 self.result.included_mut_or_default().push(Indexed::none(node));
138 Ok(())
139 }
140
141 fn graph<T>(&mut self, value: &T) -> Result<(), Self::Error>
142 where
143 T: ?Sized + ld_core::LinkedDataGraph<I>,
144 {
145 let serializer = SerializeGraph::new(self.vocabulary, self.interpretation);
146
147 let graph = value.visit_graph(serializer)?;
148 self.result.graph = Some(graph);
149 Ok(())
150 }
151
152 fn end(self) -> Result<Self::Ok, Self::Error> {
153 Ok(self.result)
154 }
155}
156
157pub(crate) fn into_type_value<I, B>(obj: Indexed<Object<I, B>>) -> Result<jsonld_core::Id<I, B>, Indexed<Object<I, B>>> {
158 match obj.index() {
159 Some(_) => Err(obj),
160 None => match obj.into_inner() {
161 Object::Node(mut node) => {
162 if node.is_empty()
163 && let Some(id) = node.id.take()
164 {
165 return Ok(id);
166 }
167 Err(Indexed::none(Object::Node(node)))
168 }
169 obj => Err(Indexed::none(obj)),
170 },
171 }
172}
173
174pub(crate) fn is_iri<V, B>(vocabulary: &V, id: &jsonld_core::Id<V::Iri, B>, iri: Iri<&str>) -> bool
175where
176 V: IriVocabulary,
177{
178 match id {
179 jsonld_core::Id::Valid(jsonld_core::ValidId::Iri(i)) => match vocabulary.iri(i) {
180 Some(i) => i == iri,
181 None => false,
182 },
183 _ => false,
184 }
185}