1use super::JsonLdContainer;
2use crate::{
3 JsonLdBacktrace, JsonLdBacktraceBuf, JsonLdDirection, JsonLdNullable, JsonLdTerm, JsonLdType,
4};
5use crate::{
6 JsonLdLenient,
7 syntax::{
8 JsonLdContext, JsonLdKeywordType,
9 context::{
10 JsonLdContextTerm, JsonLdContextType, JsonLdContextTypeContainer, JsonLdIndex,
11 JsonLdNest,
12 },
13 },
14};
15use langtag::LangTagBuf;
16use rdf_syntax::{Iri, IriBuf};
17use std::collections::HashMap;
18use std::hash::Hash;
19use std::{borrow::Borrow, fmt};
20
21pub enum JsonLdBinding {
23 Normal(JsonLdContextTerm, Box<JsonLdProcessedNormalTermDefinition>),
25
26 Type(JsonLdProcessedTypeTermDefinition),
28}
29
30pub enum JsonLdBindingRef<'a> {
32 Normal(
34 &'a JsonLdContextTerm,
35 &'a JsonLdProcessedNormalTermDefinition,
36 ),
37
38 Type(&'a JsonLdProcessedTypeTermDefinition),
40}
41
42pub enum JsonLdBindingTerm<'a> {
43 Normal(&'a JsonLdContextTerm),
44 Type,
45}
46
47impl<'a> JsonLdBindingTerm<'a> {
48 pub fn as_str(&self) -> &'a str {
49 match self {
50 Self::Normal(key) => key.as_str(),
51 Self::Type => "@type",
52 }
53 }
54}
55
56impl<'a> fmt::Display for JsonLdBindingTerm<'a> {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 self.as_str().fmt(f)
59 }
60}
61
62impl<'a> JsonLdBindingRef<'a> {
63 pub fn term(&self) -> JsonLdBindingTerm<'a> {
65 match self {
66 Self::Normal(key, _) => JsonLdBindingTerm::Normal(key),
67 Self::Type(_) => JsonLdBindingTerm::Type,
68 }
69 }
70
71 pub fn definition(&self) -> JsonLdProcessedTermDefinitionRef<'a> {
73 match self {
74 Self::Normal(_, d) => JsonLdProcessedTermDefinitionRef::Normal(d),
75 Self::Type(d) => JsonLdProcessedTermDefinitionRef::Type(d),
76 }
77 }
78}
79
80#[derive(Clone, Default)]
82pub struct JsonLdDefinitions {
83 normal: HashMap<JsonLdContextTerm, JsonLdProcessedNormalTermDefinition>,
84 type_: Option<JsonLdProcessedTypeTermDefinition>,
85}
86
87impl JsonLdDefinitions {
88 #[allow(clippy::type_complexity)]
89 pub fn into_parts(
90 self,
91 ) -> (
92 HashMap<JsonLdContextTerm, JsonLdProcessedNormalTermDefinition>,
93 Option<JsonLdProcessedTypeTermDefinition>,
94 ) {
95 (self.normal, self.type_)
96 }
97
98 pub fn len(&self) -> usize {
100 if self.type_.is_some() {
101 self.normal.len() + 1
102 } else {
103 self.normal.len()
104 }
105 }
106
107 pub fn is_empty(&self) -> bool {
109 self.type_.is_none() && self.normal.is_empty()
110 }
111
112 pub fn get<Q>(&self, term: &Q) -> Option<JsonLdProcessedTermDefinitionRef<'_>>
114 where
115 Q: ?Sized + Hash + Eq,
116 JsonLdContextTerm: Borrow<Q>,
117 JsonLdKeywordType: Borrow<Q>,
118 {
119 if JsonLdKeywordType.borrow() == term {
120 self.type_
121 .as_ref()
122 .map(JsonLdProcessedTermDefinitionRef::Type)
123 } else {
124 self.normal
125 .get(term)
126 .map(JsonLdProcessedTermDefinitionRef::Normal)
127 }
128 }
129
130 pub fn get_normal<Q>(&self, term: &Q) -> Option<&JsonLdProcessedNormalTermDefinition>
132 where
133 Q: ?Sized + Hash + Eq,
134 JsonLdContextTerm: Borrow<Q>,
135 {
136 self.normal.get(term)
137 }
138
139 pub fn get_type(&self) -> Option<&JsonLdProcessedTypeTermDefinition> {
141 self.type_.as_ref()
142 }
143
144 pub fn contains_term<Q>(&self, term: &Q) -> bool
145 where
146 Q: ?Sized + Hash + Eq,
147 JsonLdContextTerm: Borrow<Q>,
148 JsonLdKeywordType: Borrow<Q>,
149 {
150 if JsonLdKeywordType.borrow() == term {
151 self.type_.is_some()
152 } else {
153 self.normal.contains_key(term)
154 }
155 }
156
157 pub fn insert(&mut self, binding: JsonLdBinding) -> Option<JsonLdProcessedTermDefinition> {
159 match binding {
160 JsonLdBinding::Normal(key, definition) => self
161 .insert_normal(key, *definition)
162 .map(JsonLdProcessedTermDefinition::Normal),
163 JsonLdBinding::Type(definition) => self
164 .insert_type(definition)
165 .map(JsonLdProcessedTermDefinition::Type),
166 }
167 }
168
169 pub fn insert_normal(
171 &mut self,
172 term: JsonLdContextTerm,
173 definition: JsonLdProcessedNormalTermDefinition,
174 ) -> Option<JsonLdProcessedNormalTermDefinition> {
175 self.normal.insert(term, definition)
176 }
177
178 pub fn insert_type(
180 &mut self,
181 definition: JsonLdProcessedTypeTermDefinition,
182 ) -> Option<JsonLdProcessedTypeTermDefinition> {
183 self.type_.replace(definition)
184 }
185
186 pub fn set_normal(
188 &mut self,
189 term: JsonLdContextTerm,
190 definition: Option<JsonLdProcessedNormalTermDefinition>,
191 ) -> Option<JsonLdProcessedNormalTermDefinition> {
192 match definition {
193 Some(d) => self.normal.insert(term, d),
194 None => self.normal.remove(&term),
195 }
196 }
197
198 pub fn set_type(
200 &mut self,
201 definition: Option<JsonLdProcessedTypeTermDefinition>,
202 ) -> Option<JsonLdProcessedTypeTermDefinition> {
203 std::mem::replace(&mut self.type_, definition)
204 }
205
206 pub fn iter(&self) -> JsonLdDefinitionsIter<'_> {
208 JsonLdDefinitionsIter {
209 type_: self.type_.as_ref(),
210 normal: self.normal.iter(),
211 }
212 }
213}
214
215pub struct JsonLdDefinitionsIter<'a> {
216 type_: Option<&'a JsonLdProcessedTypeTermDefinition>,
217 normal: std::collections::hash_map::Iter<
218 'a,
219 JsonLdContextTerm,
220 JsonLdProcessedNormalTermDefinition,
221 >,
222}
223
224impl<'a> Iterator for JsonLdDefinitionsIter<'a> {
225 type Item = JsonLdBindingRef<'a>;
226
227 fn next(&mut self) -> Option<Self::Item> {
228 self.type_.take().map(JsonLdBindingRef::Type).or_else(|| {
229 self.normal
230 .next()
231 .map(|(k, d)| JsonLdBindingRef::Normal(k, d))
232 })
233 }
234}
235
236impl<'a> IntoIterator for &'a JsonLdDefinitions {
237 type Item = JsonLdBindingRef<'a>;
238 type IntoIter = JsonLdDefinitionsIter<'a>;
239
240 fn into_iter(self) -> Self::IntoIter {
241 self.iter()
242 }
243}
244
245pub struct JsonLdDefinitionsIntoIter {
246 type_: Option<JsonLdProcessedTypeTermDefinition>,
247 normal: std::collections::hash_map::IntoIter<
248 JsonLdContextTerm,
249 JsonLdProcessedNormalTermDefinition,
250 >,
251}
252
253impl Iterator for JsonLdDefinitionsIntoIter {
254 type Item = JsonLdBinding;
255
256 fn next(&mut self) -> Option<Self::Item> {
257 self.type_.take().map(JsonLdBinding::Type).or_else(|| {
258 self.normal
259 .next()
260 .map(|(k, d)| JsonLdBinding::Normal(k, Box::new(d)))
261 })
262 }
263}
264
265impl IntoIterator for JsonLdDefinitions {
266 type Item = JsonLdBinding;
267 type IntoIter = JsonLdDefinitionsIntoIter;
268
269 fn into_iter(self) -> Self::IntoIter {
270 JsonLdDefinitionsIntoIter {
271 type_: self.type_,
272 normal: self.normal.into_iter(),
273 }
274 }
275}
276
277#[derive(PartialEq, Eq, Clone)]
282pub struct JsonLdProcessedTypeTermDefinition {
283 pub container: JsonLdContextTypeContainer,
285
286 pub protected: bool,
288}
289
290impl Default for JsonLdProcessedTypeTermDefinition {
291 fn default() -> Self {
292 Self {
293 container: JsonLdContextTypeContainer::Set,
294 protected: false,
295 }
296 }
297}
298
299impl JsonLdProcessedTypeTermDefinition {
300 pub fn modulo_protected_field(&self) -> JsonLdModuloProtected<&Self> {
301 JsonLdModuloProtected(self)
302 }
303
304 pub fn into_syntax_definition(self) -> JsonLdContextType {
305 JsonLdContextType {
306 container: self.container,
307 protected: if self.protected { Some(true) } else { None },
308 }
309 }
310}
311
312#[derive(PartialEq, Eq, Clone)]
314pub enum JsonLdProcessedTermDefinition {
315 Type(JsonLdProcessedTypeTermDefinition),
317
318 Normal(JsonLdProcessedNormalTermDefinition),
320}
321
322impl JsonLdProcessedTermDefinition {
323 pub fn as_ref(&self) -> JsonLdProcessedTermDefinitionRef<'_> {
324 match self {
325 Self::Type(t) => JsonLdProcessedTermDefinitionRef::Type(t),
326 Self::Normal(n) => JsonLdProcessedTermDefinitionRef::Normal(n),
327 }
328 }
329
330 pub fn modulo_protected_field(
331 &self,
332 ) -> JsonLdModuloProtected<JsonLdProcessedTermDefinitionRef<'_>> {
333 JsonLdModuloProtected(self.as_ref())
334 }
335
336 pub fn value(&self) -> Option<&JsonLdTerm> {
337 match self {
338 Self::Type(_) => None,
339 Self::Normal(d) => d.value.as_ref(),
340 }
341 }
342
343 pub fn prefix(&self) -> bool {
344 match self {
345 Self::Type(_) => false,
346 Self::Normal(d) => d.prefix,
347 }
348 }
349
350 pub fn protected(&self) -> bool {
351 match self {
352 Self::Type(d) => d.protected,
353 Self::Normal(d) => d.protected,
354 }
355 }
356
357 pub fn reverse_property(&self) -> bool {
358 match self {
359 Self::Type(_) => false,
360 Self::Normal(d) => d.reverse_property,
361 }
362 }
363
364 pub fn base_url(&self) -> Option<&IriBuf> {
365 match self {
366 Self::Type(_) => None,
367 Self::Normal(d) => d.base_url.as_ref(),
368 }
369 }
370
371 pub fn context(&self) -> Option<&JsonLdContext> {
372 match self {
373 Self::Type(_) => None,
374 Self::Normal(d) => d.context.as_deref(),
375 }
376 }
377
378 pub fn container(&self) -> JsonLdContainer {
379 match self {
380 Self::Type(d) => d.container.into(),
381 Self::Normal(d) => d.container,
382 }
383 }
384
385 pub fn direction(&self) -> Option<JsonLdNullable<JsonLdDirection>> {
386 match self {
387 Self::Type(_) => None,
388 Self::Normal(d) => d.direction,
389 }
390 }
391
392 pub fn index(&self) -> Option<&JsonLdIndex> {
393 match self {
394 Self::Type(_) => None,
395 Self::Normal(d) => d.index.as_ref(),
396 }
397 }
398
399 pub fn language(&self) -> Option<JsonLdNullable<&JsonLdLenient<LangTagBuf>>> {
400 match self {
401 Self::Type(_) => None,
402 Self::Normal(d) => d.language.as_ref().map(JsonLdNullable::as_ref),
403 }
404 }
405
406 pub fn nest(&self) -> Option<&JsonLdNest> {
407 match self {
408 Self::Type(_) => None,
409 Self::Normal(d) => d.nest.as_ref(),
410 }
411 }
412
413 pub fn typ(&self) -> Option<&JsonLdType> {
414 match self {
415 Self::Type(_) => None,
416 Self::Normal(d) => d.typ.as_ref(),
417 }
418 }
419}
420
421#[derive(PartialEq, Eq)]
423pub enum JsonLdProcessedTermDefinitionRef<'a> {
424 Type(&'a JsonLdProcessedTypeTermDefinition),
426
427 Normal(&'a JsonLdProcessedNormalTermDefinition),
429}
430
431impl<'a> JsonLdProcessedTermDefinitionRef<'a> {
432 pub fn modulo_protected_field(&self) -> JsonLdModuloProtected<Self> {
433 JsonLdModuloProtected(*self)
434 }
435
436 pub fn value(&self) -> Option<&'a JsonLdTerm> {
437 match self {
438 Self::Type(_) => None,
439 Self::Normal(d) => d.value.as_ref(),
440 }
441 }
442
443 pub fn prefix(&self) -> bool {
444 match self {
445 Self::Type(_) => false,
446 Self::Normal(d) => d.prefix,
447 }
448 }
449
450 pub fn protected(&self) -> bool {
451 match self {
452 Self::Type(d) => d.protected,
453 Self::Normal(d) => d.protected,
454 }
455 }
456
457 pub fn reverse_property(&self) -> bool {
458 match self {
459 Self::Type(_) => false,
460 Self::Normal(d) => d.reverse_property,
461 }
462 }
463
464 pub fn base_url(&self) -> Option<&'a Iri> {
465 match self {
466 Self::Type(_) => None,
467 Self::Normal(d) => d.base_url.as_deref(),
468 }
469 }
470
471 pub fn context(&self) -> Option<&'a JsonLdContext> {
472 match self {
473 Self::Type(_) => None,
474 Self::Normal(d) => d.context.as_deref(),
475 }
476 }
477
478 pub fn location(&self) -> Option<&'a JsonLdBacktrace> {
481 match self {
482 Self::Type(_) => None,
483 Self::Normal(d) => Some(&d.location),
484 }
485 }
486
487 pub fn container(&self) -> JsonLdContainer {
488 match self {
489 Self::Type(d) => d.container.into(),
490 Self::Normal(d) => d.container,
491 }
492 }
493
494 pub fn direction(&self) -> Option<JsonLdNullable<JsonLdDirection>> {
495 match self {
496 Self::Type(_) => None,
497 Self::Normal(d) => d.direction,
498 }
499 }
500
501 pub fn index(&self) -> Option<&'a JsonLdIndex> {
502 match self {
503 Self::Type(_) => None,
504 Self::Normal(d) => d.index.as_ref(),
505 }
506 }
507
508 pub fn language(&self) -> Option<JsonLdNullable<&'a JsonLdLenient<LangTagBuf>>> {
509 match self {
510 Self::Type(_) => None,
511 Self::Normal(d) => d.language.as_ref().map(JsonLdNullable::as_ref),
512 }
513 }
514
515 pub fn nest(&self) -> Option<&'a JsonLdNest> {
516 match self {
517 Self::Type(_) => None,
518 Self::Normal(d) => d.nest.as_ref(),
519 }
520 }
521
522 pub fn typ(&self) -> Option<&'a JsonLdType> {
523 match self {
524 Self::Type(_) => None,
525 Self::Normal(d) => d.typ.as_ref(),
526 }
527 }
528}
529
530impl<'a> Clone for JsonLdProcessedTermDefinitionRef<'a> {
531 fn clone(&self) -> Self {
532 *self
533 }
534}
535
536impl<'a> Copy for JsonLdProcessedTermDefinitionRef<'a> {}
537
538#[derive(PartialEq, Eq, Clone, Default)]
540pub struct JsonLdProcessedNormalTermDefinition {
541 pub location: JsonLdBacktraceBuf,
543
544 pub value: Option<JsonLdTerm>,
546
547 pub prefix: bool,
549
550 pub protected: bool,
552
553 pub reverse_property: bool,
555
556 pub base_url: Option<IriBuf>,
558
559 pub context: Option<Box<JsonLdContext>>,
561
562 pub container: JsonLdContainer,
564
565 pub direction: Option<JsonLdNullable<JsonLdDirection>>,
567
568 pub index: Option<JsonLdIndex>,
570
571 pub language: Option<JsonLdNullable<JsonLdLenient<LangTagBuf>>>,
573
574 pub nest: Option<JsonLdNest>,
576
577 pub typ: Option<JsonLdType>,
579}
580
581impl JsonLdProcessedNormalTermDefinition {
582 pub fn modulo_protected_field(&self) -> JsonLdModuloProtected<&Self> {
583 JsonLdModuloProtected(self)
584 }
585
586 pub fn base_url(&self) -> Option<&IriBuf> {
587 self.base_url.as_ref()
588 }
589}
590
591pub struct JsonLdModuloProtected<T>(T);
593
594impl<'b> PartialEq<JsonLdModuloProtected<&'b JsonLdProcessedNormalTermDefinition>>
595 for JsonLdModuloProtected<&JsonLdProcessedNormalTermDefinition>
596{
597 fn eq(&self, other: &JsonLdModuloProtected<&'b JsonLdProcessedNormalTermDefinition>) -> bool {
598 self.0.prefix == other.0.prefix
600 && self.0.reverse_property == other.0.reverse_property
601 && self.0.language == other.0.language
602 && self.0.direction == other.0.direction
603 && self.0.nest == other.0.nest
604 && self.0.index == other.0.index
605 && self.0.container == other.0.container
606 && self.0.base_url == other.0.base_url
607 && self.0.value == other.0.value
608 && self.0.typ == other.0.typ
609 && self.0.context == other.0.context
610 }
611}
612
613impl Eq for JsonLdModuloProtected<&JsonLdProcessedNormalTermDefinition> {}
614
615impl<'b> PartialEq<JsonLdModuloProtected<&'b JsonLdProcessedTypeTermDefinition>>
616 for JsonLdModuloProtected<&JsonLdProcessedTypeTermDefinition>
617{
618 fn eq(&self, other: &JsonLdModuloProtected<&'b JsonLdProcessedTypeTermDefinition>) -> bool {
619 self.0.container == other.0.container
621 }
622}
623
624impl Eq for JsonLdModuloProtected<&JsonLdProcessedTypeTermDefinition> {}
625
626impl<'a, 'b> PartialEq<JsonLdModuloProtected<JsonLdProcessedTermDefinitionRef<'b>>>
627 for JsonLdModuloProtected<JsonLdProcessedTermDefinitionRef<'a>>
628{
629 fn eq(&self, other: &JsonLdModuloProtected<JsonLdProcessedTermDefinitionRef<'b>>) -> bool {
630 self.0.prefix() == other.0.prefix()
632 && self.0.reverse_property() == other.0.reverse_property()
633 && self.0.language() == other.0.language()
634 && self.0.direction() == other.0.direction()
635 && self.0.nest() == other.0.nest()
636 && self.0.index() == other.0.index()
637 && self.0.container() == other.0.container()
638 && self.0.base_url() == other.0.base_url()
639 && self.0.value() == other.0.value()
640 && self.0.typ() == other.0.typ()
641 && self.0.context() == other.0.context()
642 }
643}
644
645impl<'a> Eq for JsonLdModuloProtected<JsonLdProcessedTermDefinitionRef<'a>> {}