json_ld/core/document/
expanded.rs1use btree_indexmap::BTreeIndexSet;
2
3use crate::{
4 JsonLdIndexed, JsonLdIndexedObject, JsonLdNode, JsonLdObject, JsonLdVisit,
5 object::{JsonLdObjectMut, JsonLdObjectRef},
6};
7
8#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct JsonLdExpandedDocument(BTreeIndexSet<JsonLdIndexedObject>);
14
15impl JsonLdExpandedDocument {
16 #[inline(always)]
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 #[inline(always)]
22 pub fn len(&self) -> usize {
23 self.0.len()
24 }
25
26 #[inline(always)]
27 pub fn is_empty(&self) -> bool {
28 self.0.is_empty()
29 }
30
31 #[inline(always)]
32 pub fn objects(&self) -> &BTreeIndexSet<JsonLdIndexedObject> {
33 &self.0
34 }
35
36 #[inline(always)]
37 pub fn into_objects(self) -> BTreeIndexSet<JsonLdIndexedObject> {
38 self.0
39 }
40
41 #[inline(always)]
42 pub fn iter(&self) -> btree_indexmap::set::Iter<'_, JsonLdIndexedObject> {
43 self.0.iter()
44 }
45
46 pub fn main_node(&self) -> Option<&JsonLdNode> {
51 let mut result = None;
52
53 for object in self {
54 if let JsonLdObject::Node(node) = object.inner() {
55 if result.is_some() {
56 return None;
57 }
58
59 result = Some(&**node)
60 }
61 }
62
63 result
64 }
65
66 pub fn into_main_node(self) -> Option<JsonLdNode> {
71 let mut result = None;
72
73 for object in self {
74 if let JsonLdObject::Node(node) = object.into_inner() {
75 if result.is_some() {
76 return None;
77 }
78
79 result = Some(*node)
80 }
81 }
82
83 result
84 }
85
86 #[inline(always)]
87 pub fn insert(&mut self, object: JsonLdIndexedObject) -> bool {
88 self.0.insert(object)
89 }
90}
91
92#[cfg(feature = "serde")]
93impl JsonLdExpandedDocument {
94 pub fn to_json(&self) -> json_syntax::JsonValue {
97 json_syntax::to_value(self).expect("an expanded document is a valid JSON value")
102 }
103}
104
105#[cfg(feature = "serde")]
106impl From<JsonLdExpandedDocument> for json_syntax::JsonValue {
107 fn from(document: JsonLdExpandedDocument) -> Self {
108 document.to_json()
109 }
110}
111
112impl JsonLdVisit for JsonLdExpandedDocument {
113 fn visit_with(&self, f: &mut impl FnMut(JsonLdObjectRef)) {
114 self.0.visit_with(f);
115 }
116
117 fn visit_mut_with(&mut self, f: &mut impl FnMut(JsonLdObjectMut)) {
118 self.0.visit_mut_with(f);
119 }
120}
121
122impl From<JsonLdIndexed<JsonLdNode>> for JsonLdExpandedDocument {
123 fn from(value: JsonLdIndexed<JsonLdNode>) -> Self {
124 let mut result = Self::default();
125
126 result.insert(value.map_inner(JsonLdObject::node));
127
128 result
129 }
130}
131
132impl IntoIterator for JsonLdExpandedDocument {
133 type IntoIter = IntoIter;
134 type Item = JsonLdIndexedObject;
135
136 #[inline(always)]
137 fn into_iter(self) -> Self::IntoIter {
138 IntoIter(self.0.into_iter())
139 }
140}
141
142impl<'a> IntoIterator for &'a JsonLdExpandedDocument {
143 type IntoIter = btree_indexmap::set::Iter<'a, JsonLdIndexedObject>;
144 type Item = &'a JsonLdIndexedObject;
145
146 #[inline(always)]
147 fn into_iter(self) -> Self::IntoIter {
148 self.iter()
149 }
150}
151pub struct IntoIter(btree_indexmap::set::IntoIter<JsonLdIndexedObject>);
152
153impl Iterator for IntoIter {
154 type Item = JsonLdIndexedObject;
155
156 fn next(&mut self) -> Option<Self::Item> {
157 self.0.next()
158 }
159}
160
161impl FromIterator<JsonLdIndexedObject> for JsonLdExpandedDocument {
162 fn from_iter<I: IntoIterator<Item = JsonLdIndexedObject>>(iter: I) -> Self {
163 Self(iter.into_iter().collect())
164 }
165}
166
167impl Extend<JsonLdIndexedObject> for JsonLdExpandedDocument {
168 fn extend<I: IntoIterator<Item = JsonLdIndexedObject>>(&mut self, iter: I) {
169 self.0.extend(iter)
170 }
171}
172
173impl From<BTreeIndexSet<JsonLdIndexedObject>> for JsonLdExpandedDocument {
174 fn from(set: BTreeIndexSet<JsonLdIndexedObject>) -> Self {
175 Self(set)
176 }
177}
178
179#[cfg(all(test, feature = "serde"))]
180mod tests {
181 use json_syntax::JsonValue;
182 use rdf_syntax::{Id, iri};
183
184 use super::*;
185 use crate::JsonLdLenient;
186
187 #[test]
188 fn empty_document_to_json() {
189 assert_eq!(
190 JsonLdExpandedDocument::new().to_json(),
191 JsonValue::Array(Vec::new())
192 );
193 }
194
195 #[test]
196 fn node_document_to_json() {
197 let id = JsonLdLenient::Valid(Id::Iri(iri!("https://example.org/a").to_owned()));
198 let document = JsonLdExpandedDocument::from(JsonLdIndexed::new(
199 JsonLdNode::new_with_id(Some(id)),
200 None,
201 ));
202
203 let json = document.to_json();
204 let JsonValue::Array(objects) = &json else {
205 panic!("an expanded document must be a JSON array")
206 };
207 assert_eq!(objects.len(), 1);
208
209 assert_eq!(JsonValue::from(document), json);
210 }
211}