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