json_ld/core/object/node/
reverse_properties.rs1use super::JsonLdNodes;
2use crate::{
3 JsonLdIndexedNode, JsonLdLenient, JsonLdVisit,
4 object::{JsonLdObjectMut, JsonLdObjectRef},
5};
6use btree_indexmap::{BTreeIndexMap, BTreeIndexMultiSet, Comparable};
7use educe::Educe;
8use rdf_syntax::Id;
9use std::hash::Hash;
10
11pub type JsonLdReversePropertyNodes = BTreeIndexMultiSet<JsonLdIndexedNode>;
12
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[cfg_attr(feature = "serde", serde(transparent))]
17pub struct JsonLdReverseProperties(BTreeIndexMap<JsonLdLenient<Id>, JsonLdReversePropertyNodes>);
18
19impl Default for JsonLdReverseProperties {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl JsonLdReverseProperties {
26 pub fn new() -> Self {
28 Self(BTreeIndexMap::new())
29 }
30
31 #[inline(always)]
33 pub fn len(&self) -> usize {
34 self.0.len()
35 }
36
37 #[inline(always)]
39 pub fn is_empty(&self) -> bool {
40 self.0.is_empty()
41 }
42
43 #[inline(always)]
45 pub fn iter(&self) -> JsonLdReversePropertiesIter<'_> {
46 JsonLdReversePropertiesIter {
47 inner: self.0.iter(),
48 }
49 }
50
51 #[inline(always)]
53 pub fn iter_mut(&mut self) -> JsonLdReversePropertiesIterMut<'_> {
54 self.0.iter_mut()
55 }
56
57 #[inline(always)]
59 pub fn clear(&mut self) {
60 self.0.clear()
61 }
62
63 #[inline(always)]
65 pub fn contains<Q: ?Sized + Hash + Comparable<JsonLdLenient<Id>>>(&self, prop: &Q) -> bool {
66 self.0.get(prop).is_some()
67 }
68
69 #[inline(always)]
71 pub fn get<Q: ?Sized + Hash + Comparable<JsonLdLenient<Id>>>(
72 &self,
73 prop: &Q,
74 ) -> JsonLdNodes<'_> {
75 match self.0.get(prop) {
76 Some(values) => JsonLdNodes::new(Some(values.iter())),
77 None => JsonLdNodes::new(None),
78 }
79 }
80
81 #[inline(always)]
85 pub fn get_any<Q: ?Sized + Hash + Comparable<JsonLdLenient<Id>>>(
86 &self,
87 prop: &Q,
88 ) -> Option<&JsonLdIndexedNode> {
89 match self.0.get(prop) {
90 Some(values) => values.iter().next(),
91 None => None,
92 }
93 }
94
95 #[inline(always)]
97 pub fn insert(&mut self, prop: JsonLdLenient<Id>, value: JsonLdIndexedNode) {
98 if let Some(node_values) = self.0.get_mut(&prop) {
99 node_values.insert(value);
100 } else {
101 self.0.insert(prop, BTreeIndexMultiSet::singleton(value));
102 }
103 }
104
105 #[inline(always)]
107 pub fn insert_unique(&mut self, prop: JsonLdLenient<Id>, value: JsonLdIndexedNode) {
108 if let Some(node_values) = self.0.get_mut(&prop) {
109 if node_values.iter().all(|v| !v.equivalent(&value)) {
110 node_values.insert(value);
111 }
112 } else {
113 self.0.insert(prop, BTreeIndexMultiSet::singleton(value));
114 }
115 }
116
117 #[inline(always)]
119 pub fn insert_all<Objects: IntoIterator<Item = JsonLdIndexedNode>>(
120 &mut self,
121 prop: JsonLdLenient<Id>,
122 values: Objects,
123 ) {
124 if let Some(node_values) = self.0.get_mut(&prop) {
125 node_values.extend(values);
126 } else {
127 self.0.insert(prop, values.into_iter().collect());
128 }
129 }
130
131 #[inline(always)]
133 pub fn insert_all_unique<Nodes: IntoIterator<Item = JsonLdIndexedNode>>(
134 &mut self,
135 prop: JsonLdLenient<Id>,
136 values: Nodes,
137 ) {
138 if let Some(node_values) = self.0.get_mut(&prop) {
139 for value in values {
140 if node_values.iter().all(|v| !v.equivalent(&value)) {
141 node_values.insert(value);
142 }
143 }
144 } else {
145 let values = values.into_iter();
146 let mut node_values: JsonLdReversePropertyNodes =
147 BTreeIndexMultiSet::with_capacity(values.size_hint().0);
148 for value in values {
149 if node_values.iter().all(|v| !v.equivalent(&value)) {
150 node_values.insert(value);
151 }
152 }
153
154 self.0.insert(prop, node_values);
155 }
156 }
157
158 pub fn set(&mut self, prop: JsonLdLenient<Id>, values: JsonLdReversePropertyNodes) {
159 self.0.insert(prop, values);
160 }
161
162 pub fn extend_unique<N>(&mut self, iter: impl IntoIterator<Item = (JsonLdLenient<Id>, N)>)
163 where
164 N: IntoIterator<Item = JsonLdIndexedNode>,
165 {
166 for (prop, values) in iter {
167 self.insert_all_unique(prop, values)
168 }
169 }
170
171 #[inline(always)]
173 pub fn remove(&mut self, prop: &JsonLdLenient<Id>) -> Option<JsonLdReversePropertyNodes> {
174 self.0.swap_remove(prop)
175 }
176}
177
178impl JsonLdVisit for JsonLdReverseProperties {
179 fn visit_with(&self, f: &mut impl FnMut(JsonLdObjectRef)) {
180 for (_, t) in self {
181 t.visit_with(f);
182 }
183 }
184
185 fn visit_mut_with(&mut self, f: &mut impl FnMut(JsonLdObjectMut)) {
186 for (_, t) in self {
187 t.visit_mut_with(f);
188 }
189 }
190}
191
192impl<N> FromIterator<(JsonLdLenient<Id>, N)> for JsonLdReverseProperties
193where
194 N: IntoIterator<Item = JsonLdIndexedNode>,
195{
196 fn from_iter<I: IntoIterator<Item = (JsonLdLenient<Id>, N)>>(iter: I) -> Self {
197 let mut result = Self::default();
198 for (id, values) in iter {
199 result.insert_all(id, values);
200 }
201 result
202 }
203}
204
205impl Extend<(JsonLdLenient<Id>, Vec<JsonLdIndexedNode>)> for JsonLdReverseProperties {
206 fn extend<I>(&mut self, iter: I)
207 where
208 I: IntoIterator<Item = (JsonLdLenient<Id>, Vec<JsonLdIndexedNode>)>,
209 {
210 for (prop, values) in iter {
211 self.insert_all(prop, values)
212 }
213 }
214}
215
216pub type JsonLdReverseBinding = (JsonLdLenient<Id>, JsonLdReversePropertyNodes);
219
220pub type JsonLdReverseBindingRef<'a> = (&'a JsonLdLenient<Id>, &'a [JsonLdIndexedNode]);
223
224pub type JsonLdReverseBindingMut<'a> = (&'a JsonLdLenient<Id>, &'a mut JsonLdReversePropertyNodes);
227
228impl IntoIterator for JsonLdReverseProperties {
229 type Item = JsonLdReverseBinding;
230 type IntoIter = JsonLdReversePropertiesIntoIter;
231
232 #[inline(always)]
233 fn into_iter(self) -> Self::IntoIter {
234 self.0.into_iter()
235 }
236}
237
238impl<'a> IntoIterator for &'a JsonLdReverseProperties {
239 type Item = JsonLdReverseBindingRef<'a>;
240 type IntoIter = JsonLdReversePropertiesIter<'a>;
241
242 #[inline(always)]
243 fn into_iter(self) -> Self::IntoIter {
244 self.iter()
245 }
246}
247
248impl<'a> IntoIterator for &'a mut JsonLdReverseProperties {
249 type Item = JsonLdReverseBindingMut<'a>;
250 type IntoIter = JsonLdReversePropertiesIterMut<'a>;
251
252 #[inline(always)]
253 fn into_iter(self) -> Self::IntoIter {
254 self.iter_mut()
255 }
256}
257
258pub type JsonLdReversePropertiesIntoIter =
262 btree_indexmap::map::IntoIter<JsonLdLenient<Id>, JsonLdReversePropertyNodes>;
263
264#[derive(Educe)]
268#[educe(Clone)]
269pub struct JsonLdReversePropertiesIter<'a> {
270 inner: btree_indexmap::map::Iter<'a, JsonLdLenient<Id>, JsonLdReversePropertyNodes>,
271}
272
273impl<'a> Iterator for JsonLdReversePropertiesIter<'a> {
274 type Item = JsonLdReverseBindingRef<'a>;
275
276 #[inline(always)]
277 fn size_hint(&self) -> (usize, Option<usize>) {
278 self.inner.size_hint()
279 }
280
281 #[inline(always)]
282 fn next(&mut self) -> Option<Self::Item> {
283 self.inner
284 .next()
285 .map(|(property, objects)| (property, objects.as_slice()))
286 }
287}
288
289impl<'a> ExactSizeIterator for JsonLdReversePropertiesIter<'a> {}
290
291impl<'a> std::iter::FusedIterator for JsonLdReversePropertiesIter<'a> {}
292
293pub type JsonLdReversePropertiesIterMut<'a> =
298 btree_indexmap::map::IterMut<'a, JsonLdLenient<Id>, JsonLdReversePropertyNodes>;