1use crate::context::{
2 has_keyword_form, json_node_from_events, JsonLdContext, JsonLdContextProcessor,
3 JsonLdLoadDocumentOptions, JsonLdProcessingMode, JsonLdRemoteDocument,
4};
5use crate::error::JsonLdErrorCode;
6use crate::{JsonLdSyntaxError, MAX_CONTEXT_RECURSION};
7use json_event_parser::JsonEvent;
8use oxiri::Iri;
9use std::borrow::Cow;
10use std::collections::HashMap;
11use std::error::Error;
12use std::panic::{RefUnwindSafe, UnwindSafe};
13use std::sync::{Arc, Mutex};
14
15pub enum JsonLdEvent {
16 StartObject {
17 types: Vec<String>,
18 },
19 EndObject,
20 StartProperty {
21 name: String,
22 reverse: bool,
23 },
24 EndProperty,
25 Id(String),
26 Value {
27 value: JsonLdValue,
28 r#type: Option<String>,
29 language: Option<String>,
30 },
31 StartGraph,
32 EndGraph,
33 StartList,
34 EndList,
35 StartSet,
36 EndSet,
37}
38
39pub enum JsonLdValue {
40 String(String),
41 Number(String),
42 Boolean(bool),
43}
44
45enum JsonLdExpansionState {
46 Element {
47 active_property: Option<String>,
48 is_array: bool,
49 container: &'static [&'static str],
50 reverse: bool,
51 },
52 ObjectOrContainerStart {
53 buffer: Vec<(String, Vec<JsonEvent<'static>>)>,
54 depth: usize,
55 current_key: Option<String>,
56 active_property: Option<String>,
57 container: &'static [&'static str],
58 reverse: bool,
59 },
60 ObjectOrContainerStartStreaming {
61 active_property: Option<String>,
62 container: &'static [&'static str],
63 reverse: bool,
64 },
65 Context {
66 buffer: Vec<JsonEvent<'static>>,
67 depth: usize,
68 active_property: Option<String>,
69 container: &'static [&'static str],
70 reverse: bool,
71 },
72 ObjectStart {
73 types: Vec<String>,
74 id: Option<String>,
75 seen_type: bool,
76 active_property: Option<String>,
77 reverse: bool,
78 },
79 ObjectType {
80 types: Vec<String>,
81 id: Option<String>,
82 is_array: bool,
83 active_property: Option<String>,
84 reverse: bool,
85 },
86 ObjectId {
87 types: Vec<String>,
88 id: Option<String>,
89 from_start: bool,
90 reverse: bool,
91 },
92 Object {
93 in_property: bool,
94 has_emitted_id: bool,
95 },
96 ReverseStart,
97 Reverse {
98 in_property: bool,
99 },
100 Value {
101 r#type: Option<String>,
102 value: Option<JsonLdValue>,
103 language: Option<String>,
104 },
105 ValueValue {
106 r#type: Option<String>,
107 language: Option<String>,
108 },
109 ValueLanguage {
110 r#type: Option<String>,
111 value: Option<JsonLdValue>,
112 },
113 ValueType {
114 value: Option<JsonLdValue>,
115 language: Option<String>,
116 },
117 Index,
118 Graph,
119 RootGraph,
120 ListOrSetContainer {
121 needs_end_object: bool,
122 end_event: Option<JsonLdEvent>,
123 },
124 IndexContainer {
125 active_property: Option<String>,
126 },
127 LanguageContainer,
128 LanguageContainerValue {
129 language: String,
130 is_array: bool,
131 },
132 Skip {
133 is_array: bool,
134 },
135}
136
137pub struct JsonLdExpansionConverter {
139 state: Vec<JsonLdExpansionState>,
140 context: Vec<(JsonLdContext, usize)>,
141 is_end: bool,
142 streaming: bool,
143 lenient: bool,
144 base_url: Option<Iri<String>>,
145 context_processor: JsonLdContextProcessor,
146}
147
148#[allow(clippy::expect_used, clippy::unwrap_in_result)]
149impl JsonLdExpansionConverter {
150 pub fn new(
151 base_url: Option<Iri<String>>,
152 streaming: bool,
153 lenient: bool,
154 processing_mode: JsonLdProcessingMode,
155 ) -> Self {
156 Self {
157 state: vec![JsonLdExpansionState::Element {
158 active_property: None,
159 is_array: false,
160 container: &[],
161 reverse: false,
162 }],
163 context: vec![(JsonLdContext::new_empty(base_url.clone()), 0)],
164 is_end: false,
165 streaming,
166 lenient,
167 base_url,
168 context_processor: JsonLdContextProcessor {
169 processing_mode,
170 lenient,
171 max_context_recursion: MAX_CONTEXT_RECURSION,
172 remote_context_cache: Arc::new(Mutex::new(HashMap::new())), load_document_callback: None,
174 },
175 }
176 }
177
178 pub fn is_end(&self) -> bool {
179 self.is_end
180 }
181
182 pub fn with_load_document_callback(
183 mut self,
184 callback: impl Fn(
185 &str,
186 &JsonLdLoadDocumentOptions,
187 ) -> Result<JsonLdRemoteDocument, Box<dyn Error + Send + Sync>>
188 + Send
189 + Sync
190 + UnwindSafe
191 + RefUnwindSafe
192 + 'static,
193 ) -> Self {
194 self.context_processor.load_document_callback = Some(Arc::new(callback));
195 self
196 }
197
198 pub fn convert_event(
199 &mut self,
200 event: JsonEvent<'_>,
201 results: &mut Vec<JsonLdEvent>,
202 errors: &mut Vec<JsonLdSyntaxError>,
203 ) {
204 if self.state.len() > 4096 {
205 errors.push(JsonLdSyntaxError::msg("Too large state stack"));
206 return;
207 }
208 if event == JsonEvent::Eof {
209 self.is_end = true;
210 return;
211 }
212
213 let state = self.state.pop().expect("Empty stack");
215 match state {
216 JsonLdExpansionState::Element {
217 active_property,
218 is_array,
219 container,
220 reverse,
221 } => {
222 match event {
223 JsonEvent::Null => {
224 if is_array {
226 self.state.push(JsonLdExpansionState::Element {
227 active_property,
228 is_array,
229 container,
230 reverse,
231 });
232 }
233 }
234 JsonEvent::String(value) => self.on_literal_value(
235 JsonLdValue::String(value.into()),
236 active_property,
237 is_array,
238 container,
239 reverse,
240 results,
241 errors,
242 ),
243 JsonEvent::Number(value) => self.on_literal_value(
244 JsonLdValue::Number(value.into()),
245 active_property,
246 is_array,
247 container,
248 reverse,
249 results,
250 errors,
251 ),
252 JsonEvent::Boolean(value) => self.on_literal_value(
253 JsonLdValue::Boolean(value),
254 active_property,
255 is_array,
256 container,
257 reverse,
258 results,
259 errors,
260 ),
261 JsonEvent::StartArray => {
262 if is_array {
264 self.state.push(JsonLdExpansionState::Element {
265 active_property: active_property.clone(),
266 is_array,
267 container,
268 reverse,
269 });
270 } else if container.contains(&"@list") {
271 if reverse {
272 errors.push(JsonLdSyntaxError::msg_and_code(
273 "Lists are not allowed inside of reverse properties",
274 JsonLdErrorCode::InvalidReversePropertyValue,
275 ))
276 }
277 results.push(JsonLdEvent::StartList);
278 self.state.push(JsonLdExpansionState::ListOrSetContainer {
279 needs_end_object: false,
280 end_event: Some(JsonLdEvent::EndList),
281 })
282 } else if container.contains(&"@set") {
283 results.push(JsonLdEvent::StartSet);
284 self.state.push(JsonLdExpansionState::ListOrSetContainer {
285 needs_end_object: false,
286 end_event: Some(JsonLdEvent::EndSet),
287 })
288 }
289 self.state.push(JsonLdExpansionState::Element {
290 active_property,
291 is_array: true,
292 container: &[],
293 reverse,
294 });
295 }
296 JsonEvent::EndArray => (),
297 JsonEvent::StartObject => {
298 if is_array {
299 self.state.push(JsonLdExpansionState::Element {
300 active_property: active_property.clone(),
301 is_array,
302 container,
303 reverse,
304 });
305 } else if container.contains(&"@index") {
306 self.state
307 .push(JsonLdExpansionState::IndexContainer { active_property });
308 return;
309 } else if container.contains(&"@language") {
310 self.state.push(JsonLdExpansionState::LanguageContainer);
311 return;
312 }
313 self.push_same_context();
314 self.state.push(if self.streaming {
315 JsonLdExpansionState::ObjectOrContainerStartStreaming {
316 active_property,
317 container,
318 reverse,
319 }
320 } else {
321 JsonLdExpansionState::ObjectOrContainerStart {
322 buffer: Vec::new(),
323 depth: 1,
324 current_key: None,
325 active_property,
326 container,
327 reverse,
328 }
329 });
330 }
331 JsonEvent::EndObject | JsonEvent::ObjectKey(_) | JsonEvent::Eof => {
332 unreachable!()
333 }
334 }
335 }
336 JsonLdExpansionState::ObjectOrContainerStart {
337 mut buffer,
338 mut depth,
339 mut current_key,
340 active_property,
341 container,
342 reverse,
343 } => {
344 match event {
346 JsonEvent::String(_)
347 | JsonEvent::Number(_)
348 | JsonEvent::Boolean(_)
349 | JsonEvent::Null => {
350 buffer.last_mut().unwrap().1.push(to_owned_event(event));
351 }
352 JsonEvent::ObjectKey(key) => {
353 if depth == 1 {
354 buffer.push((key.clone().into(), Vec::new()));
355 current_key = Some(key.into());
356 } else {
357 buffer
358 .last_mut()
359 .unwrap()
360 .1
361 .push(to_owned_event(JsonEvent::ObjectKey(key)));
362 }
363 }
364 JsonEvent::EndArray | JsonEvent::EndObject => {
365 if depth > 1 {
366 buffer.last_mut().unwrap().1.push(to_owned_event(event));
367 }
368 depth -= 1;
369 }
370 JsonEvent::StartArray | JsonEvent::StartObject => {
371 buffer.last_mut().unwrap().1.push(to_owned_event(event));
372 depth += 1;
373 }
374 JsonEvent::Eof => unreachable!(),
375 }
376 if depth == 0 {
377 let mut context_value = None;
379 let mut type_data = None;
380 let mut id_data = None;
381 let mut graph_data = Vec::new();
382 let mut other_data = Vec::with_capacity(buffer.len());
383 for (key, value) in buffer {
384 let expanded = self.expand_iri(key.as_str().into(), false, true, errors);
385 match expanded.as_deref() {
386 Some("@context") => {
387 if context_value.is_some() {
388 errors.push(JsonLdSyntaxError::msg("@context is defined twice"))
389 }
390 context_value = Some(value);
391 }
392 Some("@type") => {
393 if type_data.is_some() {
394 errors.push(JsonLdSyntaxError::msg("@type is defined twice"))
395 }
396 type_data = Some((key, value));
397 }
398 Some("@id") => {
399 if id_data.is_some() {
400 errors.push(JsonLdSyntaxError::msg("@id is defined twice"))
401 }
402 id_data = Some((key, value));
403 }
404 Some("@graph") => {
405 graph_data.push((key, value));
406 }
407 _ => other_data.push((key, value)),
408 }
409 }
410 self.state
411 .push(JsonLdExpansionState::ObjectOrContainerStartStreaming {
412 active_property,
413 container,
414 reverse,
415 });
416
417 if let Some(context) = context_value {
419 self.push_new_context(context, errors);
420 }
421 for (key, value) in type_data
422 .into_iter()
423 .chain(id_data)
424 .chain(other_data)
425 .chain(graph_data)
426 {
427 self.convert_event(JsonEvent::ObjectKey(key.into()), results, errors);
428 for event in value {
429 self.convert_event(event, results, errors);
430 }
431 }
432 self.convert_event(JsonEvent::EndObject, results, errors);
433 } else {
434 self.state
435 .push(JsonLdExpansionState::ObjectOrContainerStart {
436 buffer,
437 depth,
438 current_key,
439 active_property,
440 container,
441 reverse,
442 });
443 }
444 }
445 JsonLdExpansionState::ObjectOrContainerStartStreaming {
446 active_property,
447 container,
448 reverse,
449 } => match event {
450 JsonEvent::ObjectKey(key) => {
451 if let Some(iri) = self.expand_iri(key.as_ref().into(), false, true, errors) {
452 match iri.as_ref() {
453 "@context" => self.state.push(JsonLdExpansionState::Context {
454 buffer: Vec::new(),
455 depth: 0,
456 active_property,
457 container,
458 reverse,
459 }),
460 "@index" => {
461 self.state.push(
462 JsonLdExpansionState::ObjectOrContainerStartStreaming {
463 active_property,
464 container,
465 reverse,
466 },
467 );
468 self.state.push(JsonLdExpansionState::Index);
469 }
470 "@list" => {
471 if active_property.is_some() {
472 if reverse {
473 errors.push(JsonLdSyntaxError::msg_and_code(
474 "Lists are not allowed inside of reverse properties",
475 JsonLdErrorCode::InvalidReversePropertyValue,
476 ))
477 }
478 self.state.push(JsonLdExpansionState::ListOrSetContainer {
479 needs_end_object: true,
480 end_event: Some(JsonLdEvent::EndList),
481 });
482 self.state.push(JsonLdExpansionState::Element {
483 is_array: false,
484 active_property,
485 container: &[],
486 reverse: false,
487 });
488 results.push(JsonLdEvent::StartList);
489 } else {
490 self.state
492 .push(JsonLdExpansionState::Skip { is_array: false });
493 self.state
494 .push(JsonLdExpansionState::Skip { is_array: false });
495 }
496 }
497 "@set" => {
498 let has_property = active_property.is_some();
499 self.state.push(JsonLdExpansionState::ListOrSetContainer {
500 needs_end_object: true,
501 end_event: has_property.then_some(JsonLdEvent::EndSet),
502 });
503 self.state.push(JsonLdExpansionState::Element {
504 is_array: false,
505 active_property,
506 container: &[],
507 reverse: false,
508 });
509 if has_property {
510 results.push(JsonLdEvent::StartSet);
511 }
512 }
513 _ => {
514 if container.contains(&"@list") {
515 results.push(JsonLdEvent::StartList);
516 self.state.push(JsonLdExpansionState::ListOrSetContainer {
517 needs_end_object: false,
518 end_event: Some(JsonLdEvent::EndList),
519 });
520 } else if container.contains(&"@set") {
521 results.push(JsonLdEvent::StartSet);
522 self.state.push(JsonLdExpansionState::ListOrSetContainer {
523 needs_end_object: false,
524 end_event: Some(JsonLdEvent::EndSet),
525 });
526 }
527 self.state.push(JsonLdExpansionState::ObjectStart {
528 types: Vec::new(),
529 id: None,
530 seen_type: false,
531 active_property,
532 reverse,
533 });
534 self.convert_event(JsonEvent::ObjectKey(key), results, errors)
535 }
536 }
537 } else {
538 self.state.push(JsonLdExpansionState::ObjectStart {
539 types: Vec::new(),
540 id: None,
541 seen_type: false,
542 active_property,
543 reverse,
544 });
545 self.convert_event(JsonEvent::ObjectKey(key), results, errors)
546 }
547 }
548 JsonEvent::EndObject => {
549 self.state.push(JsonLdExpansionState::ObjectStart {
550 types: Vec::new(),
551 id: None,
552 seen_type: false,
553 active_property,
554 reverse,
555 });
556 self.convert_event(JsonEvent::EndObject, results, errors)
557 }
558 _ => unreachable!("Inside of an object"),
559 },
560 JsonLdExpansionState::Context {
561 mut buffer,
562 mut depth,
563 active_property,
564 container,
565 reverse,
566 } => {
567 match event {
568 JsonEvent::String(_)
569 | JsonEvent::Number(_)
570 | JsonEvent::Boolean(_)
571 | JsonEvent::Null
572 | JsonEvent::ObjectKey(_) => buffer.push(to_owned_event(event)),
573 JsonEvent::EndArray | JsonEvent::EndObject => {
574 buffer.push(to_owned_event(event));
575 depth -= 1;
576 }
577 JsonEvent::StartArray | JsonEvent::StartObject => {
578 buffer.push(to_owned_event(event));
579 depth += 1;
580 }
581 JsonEvent::Eof => unreachable!(),
582 }
583 if depth == 0 {
584 self.push_new_context(buffer, errors);
585 self.state
586 .push(JsonLdExpansionState::ObjectOrContainerStartStreaming {
587 active_property,
588 container,
589 reverse,
590 });
591 } else {
592 self.state.push(JsonLdExpansionState::Context {
593 buffer,
594 depth,
595 active_property,
596 container,
597 reverse,
598 });
599 }
600 }
601 JsonLdExpansionState::ObjectStart {
602 types,
603 id,
604 seen_type,
605 active_property,
606 reverse,
607 } => match event {
608 JsonEvent::ObjectKey(key) => {
609 if let Some(iri) = self.expand_iri(key.as_ref().into(), false, true, errors) {
610 match iri.as_ref() {
611 "@type" => {
612 if seen_type && !self.lenient {
613 errors.push(JsonLdSyntaxError::msg_and_code(
614 "@type must be the first key of an object or right after @context",
615 JsonLdErrorCode::InvalidStreamingKeyOrder,
616 ))
617 }
618 self.state.push(JsonLdExpansionState::ObjectType {
619 id,
620 types,
621 is_array: false,
622 active_property,
623 reverse,
624 });
625 }
626 "@value" | "@language" => {
627 if types.len() > 1 {
628 errors.push(JsonLdSyntaxError::msg_and_code(
629 "Only a single @type is allowed when @value is present",
630 JsonLdErrorCode::InvalidTypedValue,
631 ));
632 }
633 if id.is_some() {
634 errors.push(JsonLdSyntaxError::msg_and_code(
635 "@value and @id are incompatible",
636 JsonLdErrorCode::InvalidValueObject,
637 ));
638 }
639 if reverse {
640 errors.push(JsonLdSyntaxError::msg_and_code(
641 "Literals are not allowed inside of reverse properties",
642 JsonLdErrorCode::InvalidReversePropertyValue,
643 ))
644 }
645 self.state.push(JsonLdExpansionState::Value {
646 r#type: types.into_iter().next(),
647 value: None,
648 language: None,
649 });
650 self.convert_event(JsonEvent::ObjectKey(key), results, errors);
651 }
652 "@id" => {
653 if id.is_some() {
654 errors.push(JsonLdSyntaxError::msg_and_code(
655 "Only a single @id is allowed",
656 JsonLdErrorCode::CollidingKeywords,
657 ));
658 }
659 self.state.push(JsonLdExpansionState::ObjectId {
660 types,
661 id,
662 from_start: true,
663 reverse,
664 });
665 }
666 "@graph"
667 if id.is_none() && types.is_empty() && self.state.is_empty() =>
668 {
669 self.state.push(JsonLdExpansionState::RootGraph);
671 self.state.push(JsonLdExpansionState::Element {
672 active_property: None,
673 is_array: false,
674 container: &[],
675 reverse: false,
676 })
677 }
678 "@index" => {
679 self.state.push(JsonLdExpansionState::ObjectStart {
680 types,
681 id,
682 seen_type,
683 active_property,
684 reverse,
685 });
686 self.state.push(JsonLdExpansionState::Index);
687 }
688 _ => {
689 results.push(JsonLdEvent::StartObject { types });
690 let has_emitted_id = id.is_some();
691 if let Some(id) = id {
692 results.push(JsonLdEvent::Id(id));
693 }
694 self.state.push(JsonLdExpansionState::Object {
695 in_property: false,
696 has_emitted_id,
697 });
698 self.convert_event(JsonEvent::ObjectKey(key), results, errors);
699 }
700 }
701 } else {
702 self.state.push(JsonLdExpansionState::ObjectStart {
703 types,
704 id,
705 seen_type: true,
706 active_property,
707 reverse,
708 });
709 self.state
710 .push(JsonLdExpansionState::Skip { is_array: false });
711 }
712 }
713 JsonEvent::EndObject => {
714 results.push(JsonLdEvent::StartObject { types });
715 if let Some(id) = id {
716 results.push(JsonLdEvent::Id(id));
717 }
718 results.push(JsonLdEvent::EndObject);
719 self.pop_context();
720 }
721 _ => unreachable!("Inside of an object"),
722 },
723 JsonLdExpansionState::ObjectType {
724 mut types,
725 id,
726 is_array,
727 active_property,
728 reverse,
729 } => {
730 match event {
731 JsonEvent::Null | JsonEvent::Number(_) | JsonEvent::Boolean(_) => {
732 errors.push(JsonLdSyntaxError::msg_and_code(
734 "@type value must be a string",
735 JsonLdErrorCode::InvalidTypeValue,
736 ));
737 if is_array {
738 self.state.push(JsonLdExpansionState::ObjectType {
739 types,
740 id,
741 is_array,
742 active_property,
743 reverse,
744 });
745 } else {
746 self.state.push(JsonLdExpansionState::ObjectStart {
747 types,
748 id,
749 seen_type: true,
750 active_property,
751 reverse,
752 });
753 }
754 }
755 JsonEvent::String(value) => {
756 if let Some(iri) = self.expand_iri(value, true, true, errors) {
758 if has_keyword_form(&iri) {
759 errors.push(JsonLdSyntaxError::msg(format!(
760 "{iri} is not a valid value for @type"
761 )));
762 } else {
763 types.push(iri.into());
764 }
765 }
766 if is_array {
767 self.state.push(JsonLdExpansionState::ObjectType {
768 types,
769 id,
770 is_array,
771 active_property,
772 reverse,
773 });
774 } else {
775 self.state.push(JsonLdExpansionState::ObjectStart {
776 types,
777 id,
778 seen_type: true,
779 active_property,
780 reverse,
781 });
782 }
783 }
784 JsonEvent::StartArray => {
785 self.state.push(JsonLdExpansionState::ObjectType {
786 types,
787 id,
788 is_array: true,
789 active_property,
790 reverse,
791 });
792 if is_array {
793 errors.push(JsonLdSyntaxError::msg_and_code(
794 "@type cannot contain a nested array",
795 JsonLdErrorCode::InvalidTypeValue,
796 ));
797 self.state
798 .push(JsonLdExpansionState::Skip { is_array: true });
799 }
800 }
801 JsonEvent::EndArray => {
802 self.state.push(JsonLdExpansionState::ObjectStart {
803 types,
804 id,
805 seen_type: true,
806 active_property,
807 reverse,
808 });
809 }
810 JsonEvent::StartObject => {
811 errors.push(JsonLdSyntaxError::msg_and_code(
813 "@type value must be a string",
814 JsonLdErrorCode::InvalidTypeValue,
815 ));
816 if is_array {
817 self.state.push(JsonLdExpansionState::ObjectType {
818 types,
819 id,
820 is_array: true,
821 active_property,
822 reverse,
823 });
824 } else {
825 self.state.push(JsonLdExpansionState::ObjectStart {
826 types,
827 id,
828 seen_type: true,
829 active_property,
830 reverse,
831 });
832 }
833 self.state
834 .push(JsonLdExpansionState::Skip { is_array: false });
835 }
836 JsonEvent::ObjectKey(_) | JsonEvent::EndObject | JsonEvent::Eof => {
837 unreachable!()
838 }
839 }
840 }
841 JsonLdExpansionState::ObjectId {
842 types,
843 mut id,
844 from_start,
845 reverse,
846 } => {
847 if let JsonEvent::String(new_id) = event {
848 if let Some(new_id) = self.expand_iri(new_id, true, false, errors) {
849 if has_keyword_form(&new_id) {
850 errors.push(JsonLdSyntaxError::msg(
851 "@id value must be an IRI or a blank node",
852 ));
853 } else {
854 id = Some(new_id.into());
855 }
856 }
857 self.state.push(if from_start {
858 JsonLdExpansionState::ObjectStart {
859 types,
860 id,
861 seen_type: true,
862 active_property: None,
863 reverse,
864 }
865 } else {
866 if let Some(id) = id {
867 results.push(JsonLdEvent::Id(id));
868 }
869 JsonLdExpansionState::Object {
870 in_property: false,
871 has_emitted_id: true,
872 }
873 })
874 } else {
875 errors.push(JsonLdSyntaxError::msg_and_code(
876 "@id value must be a string",
877 JsonLdErrorCode::InvalidIdValue,
878 ));
879 self.state.push(if from_start {
880 JsonLdExpansionState::ObjectStart {
881 types,
882 id,
883 seen_type: true,
884 active_property: None,
885 reverse,
886 }
887 } else {
888 JsonLdExpansionState::Object {
889 in_property: false,
890 has_emitted_id: true,
891 }
892 });
893 self.state
894 .push(JsonLdExpansionState::Skip { is_array: false });
895 self.convert_event(event, results, errors);
896 }
897 }
898 JsonLdExpansionState::Object {
899 in_property,
900 has_emitted_id,
901 } => {
902 if in_property {
903 results.push(JsonLdEvent::EndProperty);
904 }
905 match event {
906 JsonEvent::EndObject => {
907 results.push(JsonLdEvent::EndObject);
908 self.pop_context();
909 }
910 JsonEvent::ObjectKey(key) => {
911 if let Some(iri) = self.expand_iri(key.as_ref().into(), false, true, errors)
912 {
913 match iri.as_ref() {
914 "@id" => {
915 if has_emitted_id {
916 errors.push(JsonLdSyntaxError::msg("Duplicated @id key"));
917 self.state.push(JsonLdExpansionState::Object {
918 in_property: false,
919 has_emitted_id: true,
920 });
921 self.state
922 .push(JsonLdExpansionState::Skip { is_array: false });
923 } else {
924 self.state.push(JsonLdExpansionState::ObjectId {
925 types: Vec::new(),
926 id: None,
927 from_start: false,
928 reverse: false,
929 });
930 }
931 }
932 "@graph" => {
933 self.state.push(JsonLdExpansionState::Object {
934 in_property: false,
935 has_emitted_id,
936 });
937 self.state.push(JsonLdExpansionState::Graph);
938 self.state.push(JsonLdExpansionState::Element {
939 is_array: false,
940 active_property: None,
941 container: &[],
942 reverse: false,
943 });
944 results.push(JsonLdEvent::StartGraph);
945 }
946 "@context" => {
947 errors.push(JsonLdSyntaxError::msg_and_code(
948 "@context must be the first key of an object",
949 JsonLdErrorCode::InvalidStreamingKeyOrder,
950 ));
951 self.state.push(JsonLdExpansionState::Object {
952 in_property: false,
953 has_emitted_id,
954 });
955 self.state
956 .push(JsonLdExpansionState::Skip { is_array: false });
957 }
958 "@type" => {
959 errors.push(JsonLdSyntaxError::msg_and_code(
961 "@type must be the first key of an object or right after @context",
962 JsonLdErrorCode::InvalidStreamingKeyOrder,
963 ));
964 self.state.push(JsonLdExpansionState::Object {
965 in_property: false,
966 has_emitted_id,
967 });
968 self.state
969 .push(JsonLdExpansionState::Skip { is_array: false });
970 }
971 "@index" => {
972 self.state.push(JsonLdExpansionState::Object {
973 in_property: false,
974 has_emitted_id,
975 });
976 self.state.push(JsonLdExpansionState::Index);
977 }
978 "@reverse" => {
979 self.state.push(JsonLdExpansionState::Object {
980 in_property: false,
981 has_emitted_id,
982 });
983 self.state.push(JsonLdExpansionState::ReverseStart);
984 }
985 _ if has_keyword_form(&iri) => {
986 errors.push(if iri == "@list" || iri == "@set" {
987 JsonLdSyntaxError::msg_and_code(
988 "@list and @set must be the only keys of an object",
989 JsonLdErrorCode::InvalidSetOrListObject,
990 )
991 } else if iri == "@context" {
992 JsonLdSyntaxError::msg_and_code(
993 "@context must be the first key of an object",
994 JsonLdErrorCode::InvalidStreamingKeyOrder,
995 )
996 } else {
997 JsonLdSyntaxError::msg(format!(
998 "Unsupported JSON-LD keyword: {iri}"
999 ))
1000 });
1001 self.state.push(JsonLdExpansionState::Object {
1002 in_property: false,
1003 has_emitted_id,
1004 });
1005 self.state
1006 .push(JsonLdExpansionState::Skip { is_array: false });
1007 }
1008 _ => {
1009 let (container, reverse) = self
1010 .context()
1011 .term_definitions
1012 .get(key.as_ref())
1013 .map_or(([].as_slice(), false), |term_definition| {
1014 (
1015 term_definition.container_mapping,
1016 term_definition.reverse_property,
1017 )
1018 });
1019 self.state.push(JsonLdExpansionState::Object {
1020 in_property: true,
1021 has_emitted_id,
1022 });
1023 self.state.push(JsonLdExpansionState::Element {
1024 active_property: Some(key.clone().into()),
1025 is_array: false,
1026 container,
1027 reverse,
1028 });
1029 results.push(JsonLdEvent::StartProperty {
1030 name: iri.into(),
1031 reverse,
1032 });
1033 }
1034 }
1035 } else {
1036 self.state.push(JsonLdExpansionState::Object {
1037 in_property: false,
1038 has_emitted_id,
1039 });
1040 self.state
1041 .push(JsonLdExpansionState::Skip { is_array: false });
1042 }
1043 }
1044 JsonEvent::Null
1045 | JsonEvent::String(_)
1046 | JsonEvent::Number(_)
1047 | JsonEvent::Boolean(_)
1048 | JsonEvent::StartArray
1049 | JsonEvent::EndArray
1050 | JsonEvent::StartObject
1051 | JsonEvent::Eof => unreachable!(),
1052 }
1053 }
1054 JsonLdExpansionState::ReverseStart => {
1055 if matches!(event, JsonEvent::StartObject) {
1056 self.state
1057 .push(JsonLdExpansionState::Reverse { in_property: false });
1058 } else {
1059 errors.push(JsonLdSyntaxError::msg_and_code(
1060 "@reverse value must be a JSON object",
1061 JsonLdErrorCode::InvalidReverseValue,
1062 ));
1063 self.state
1064 .push(JsonLdExpansionState::Skip { is_array: false });
1065 self.convert_event(event, results, errors);
1066 }
1067 }
1068 JsonLdExpansionState::Reverse { in_property } => {
1069 if in_property {
1070 results.push(JsonLdEvent::EndProperty);
1071 }
1072 match event {
1073 JsonEvent::EndObject => (),
1074 JsonEvent::ObjectKey(key) => {
1075 if let Some(iri) = self.expand_iri(key.as_ref().into(), false, true, errors)
1076 {
1077 if has_keyword_form(&iri) {
1078 errors.push(JsonLdSyntaxError::msg_and_code(
1079 format!(
1080 "@reverse object value cannot contain any keyword, found {iri}",
1081 ),
1082 JsonLdErrorCode::InvalidReversePropertyMap,
1083 ));
1084 self.state
1085 .push(JsonLdExpansionState::Reverse { in_property: false });
1086 self.state
1087 .push(JsonLdExpansionState::Skip { is_array: false });
1088 } else {
1089 let (container, reverse) = self
1090 .context()
1091 .term_definitions
1092 .get(key.as_ref())
1093 .map_or(([].as_slice(), false), |term_definition| {
1094 (
1095 term_definition.container_mapping,
1096 term_definition.reverse_property,
1097 )
1098 });
1099 let reverse = !reverse; self.state
1101 .push(JsonLdExpansionState::Reverse { in_property: true });
1102 self.state.push(JsonLdExpansionState::Element {
1103 active_property: Some(key.clone().into()),
1104 is_array: false,
1105 container,
1106 reverse,
1107 });
1108 results.push(JsonLdEvent::StartProperty {
1109 name: iri.into(),
1110 reverse,
1111 });
1112 }
1113 } else {
1114 self.state
1115 .push(JsonLdExpansionState::Reverse { in_property: false });
1116 self.state
1117 .push(JsonLdExpansionState::Skip { is_array: false });
1118 }
1119 }
1120 JsonEvent::Null
1121 | JsonEvent::String(_)
1122 | JsonEvent::Number(_)
1123 | JsonEvent::Boolean(_)
1124 | JsonEvent::StartArray
1125 | JsonEvent::EndArray
1126 | JsonEvent::StartObject
1127 | JsonEvent::Eof => unreachable!(),
1128 }
1129 }
1130 JsonLdExpansionState::Value {
1131 r#type,
1132 value,
1133 language,
1134 } => match event {
1135 JsonEvent::ObjectKey(key) => {
1136 if let Some(iri) = self.expand_iri(key, false, true, errors) {
1137 match iri.as_ref() {
1138 "@value" => {
1139 if value.is_some() {
1140 errors.push(JsonLdSyntaxError::msg_and_code(
1141 "@value cannot be set multiple times",
1142 JsonLdErrorCode::InvalidValueObject,
1143 ));
1144 self.state.push(JsonLdExpansionState::Value {
1145 r#type,
1146 value,
1147 language,
1148 });
1149 self.state
1150 .push(JsonLdExpansionState::Skip { is_array: false });
1151 } else {
1152 self.state.push(JsonLdExpansionState::ValueValue {
1153 r#type,
1154 language,
1155 });
1156 }
1157 }
1158 "@language" => {
1159 if language.is_some() {
1160 errors.push(JsonLdSyntaxError::msg_and_code(
1161 "@language cannot be set multiple times",
1162 JsonLdErrorCode::CollidingKeywords,
1163 ));
1164 self.state.push(JsonLdExpansionState::Value {
1165 r#type,
1166 value,
1167 language,
1168 });
1169 self.state
1170 .push(JsonLdExpansionState::Skip { is_array: false });
1171 } else {
1172 self.state.push(JsonLdExpansionState::ValueLanguage {
1173 r#type,
1174 value,
1175 });
1176 }
1177 }
1178 "@type" => {
1179 if !self.lenient {
1180 errors.push(JsonLdSyntaxError::msg_and_code(
1181 "@type must be the first key of an object or right after @context",
1182 JsonLdErrorCode::InvalidStreamingKeyOrder,
1183 ))
1184 }
1185 if r#type.is_some() {
1186 errors.push(JsonLdSyntaxError::msg_and_code(
1187 "@type cannot be set multiple times",
1188 JsonLdErrorCode::CollidingKeywords,
1189 ));
1190 self.state.push(JsonLdExpansionState::Value {
1191 r#type,
1192 value,
1193 language,
1194 });
1195 self.state
1196 .push(JsonLdExpansionState::Skip { is_array: false });
1197 } else {
1198 self.state
1199 .push(JsonLdExpansionState::ValueType { value, language });
1200 }
1201 }
1202 "@context" => {
1203 errors.push(JsonLdSyntaxError::msg_and_code(
1204 "@context must be the first key of an object",
1205 JsonLdErrorCode::InvalidStreamingKeyOrder,
1206 ));
1207 self.state.push(JsonLdExpansionState::Value {
1208 r#type,
1209 value,
1210 language,
1211 });
1212 self.state
1213 .push(JsonLdExpansionState::Skip { is_array: false });
1214 }
1215 "@index" => {
1216 self.state.push(JsonLdExpansionState::Value {
1217 r#type,
1218 value,
1219 language,
1220 });
1221 self.state.push(JsonLdExpansionState::Index);
1222 }
1223 _ if has_keyword_form(&iri) => {
1224 errors.push(JsonLdSyntaxError::msg_and_code(
1225 format!(
1226 "Unsupported JSON-Ld keyword inside of a @value: {iri}",
1227 ),
1228 JsonLdErrorCode::InvalidValueObject,
1229 ));
1230 self.state.push(JsonLdExpansionState::Value {
1231 r#type,
1232 value,
1233 language,
1234 });
1235 self.state
1236 .push(JsonLdExpansionState::Skip { is_array: false });
1237 }
1238 _ => {
1239 errors.push(JsonLdSyntaxError::msg_and_code(format!("Objects with @value cannot contain properties, {iri} found"), JsonLdErrorCode::InvalidValueObject));
1240 self.state.push(JsonLdExpansionState::Value {
1241 r#type,
1242 value,
1243 language,
1244 });
1245 self.state
1246 .push(JsonLdExpansionState::Skip { is_array: false });
1247 }
1248 }
1249 } else {
1250 self.state.push(JsonLdExpansionState::Value {
1251 r#type,
1252 value,
1253 language,
1254 });
1255 self.state
1256 .push(JsonLdExpansionState::Skip { is_array: false });
1257 }
1258 }
1259 JsonEvent::EndObject => {
1260 if let Some(value) = value {
1261 let mut is_valid = true;
1262 if language.is_some() && r#type.is_some() {
1263 errors.push(JsonLdSyntaxError::msg_and_code(
1264 "@type and @language cannot be used together",
1265 JsonLdErrorCode::InvalidValueObject,
1266 ));
1267 is_valid = false;
1268 }
1269 if language.is_some() && !matches!(value, JsonLdValue::String(_)) {
1270 errors.push(JsonLdSyntaxError::msg_and_code(
1271 "@language can be used only on a string @value",
1272 JsonLdErrorCode::InvalidLanguageTaggedValue,
1273 ));
1274 is_valid = false;
1275 }
1276 if let Some(r#type) = &r#type {
1277 if r#type.starts_with("_:") {
1278 errors.push(JsonLdSyntaxError::msg_and_code(
1279 "@type cannot be a blank node",
1280 JsonLdErrorCode::InvalidTypedValue,
1281 ));
1282 is_valid = false;
1283 } else if !self.lenient {
1284 if let Err(e) = Iri::parse(r#type.as_str()) {
1285 errors.push(JsonLdSyntaxError::msg_and_code(
1286 format!("@type value '{type}' must be an IRI: {e}"),
1287 JsonLdErrorCode::InvalidTypedValue,
1288 ));
1289 is_valid = false;
1290 }
1291 }
1292 }
1293 if is_valid {
1294 results.push(JsonLdEvent::Value {
1295 value,
1296 r#type,
1297 language,
1298 })
1299 }
1300 }
1301 self.pop_context();
1302 }
1303 JsonEvent::Null
1304 | JsonEvent::String(_)
1305 | JsonEvent::Number(_)
1306 | JsonEvent::Boolean(_)
1307 | JsonEvent::StartArray
1308 | JsonEvent::EndArray
1309 | JsonEvent::StartObject
1310 | JsonEvent::Eof => unreachable!(),
1311 },
1312 JsonLdExpansionState::ValueValue { r#type, language } => match event {
1313 JsonEvent::Null => self.state.push(JsonLdExpansionState::Value {
1314 r#type,
1315 value: None,
1316 language,
1317 }),
1318 JsonEvent::Number(value) => self.state.push(JsonLdExpansionState::Value {
1319 r#type,
1320 value: Some(JsonLdValue::Number(value.into())),
1321 language,
1322 }),
1323 JsonEvent::Boolean(value) => self.state.push(JsonLdExpansionState::Value {
1324 r#type,
1325 value: Some(JsonLdValue::Boolean(value)),
1326 language,
1327 }),
1328 JsonEvent::String(value) => self.state.push(JsonLdExpansionState::Value {
1329 r#type,
1330 value: Some(JsonLdValue::String(value.into())),
1331 language,
1332 }),
1333 _ => {
1334 errors.push(JsonLdSyntaxError::msg_and_code(
1335 "@value value must be a string, number, boolean or null",
1336 JsonLdErrorCode::InvalidValueObjectValue,
1337 ));
1338 self.state.push(JsonLdExpansionState::Value {
1339 r#type,
1340 value: None,
1341 language,
1342 });
1343 self.state
1344 .push(JsonLdExpansionState::Skip { is_array: false });
1345 self.convert_event(event, results, errors);
1346 }
1347 },
1348 JsonLdExpansionState::ValueLanguage { value, r#type } => {
1349 if let JsonEvent::String(language) = event {
1350 self.state.push(JsonLdExpansionState::Value {
1351 r#type,
1352 value,
1353 language: Some(language.into()),
1354 })
1355 } else {
1356 errors.push(JsonLdSyntaxError::msg_and_code(
1357 "@value value must be a string",
1358 JsonLdErrorCode::InvalidLanguageTaggedString,
1359 ));
1360 self.state.push(JsonLdExpansionState::Value {
1361 r#type,
1362 value,
1363 language: None,
1364 });
1365 self.state
1366 .push(JsonLdExpansionState::Skip { is_array: false });
1367 self.convert_event(event, results, errors);
1368 }
1369 }
1370 JsonLdExpansionState::ValueType { value, language } => {
1371 if let JsonEvent::String(t) = event {
1372 let mut r#type = self.expand_iri(t, true, true, errors);
1373 if let Some(iri) = &r#type {
1374 if has_keyword_form(iri) {
1375 errors.push(JsonLdSyntaxError::msg_and_code(
1376 format!("{iri} is not a valid value for @type"),
1377 JsonLdErrorCode::InvalidTypedValue,
1378 ));
1379 r#type = None
1380 }
1381 }
1382 self.state.push(JsonLdExpansionState::Value {
1383 r#type: r#type.map(Into::into),
1384 value,
1385 language,
1386 })
1387 } else {
1388 errors.push(JsonLdSyntaxError::msg_and_code(
1389 "@type value must be a string when @value is present",
1390 JsonLdErrorCode::InvalidTypedValue,
1391 ));
1392 self.state.push(JsonLdExpansionState::Value {
1393 r#type: None,
1394 value,
1395 language,
1396 });
1397 self.state
1398 .push(JsonLdExpansionState::Skip { is_array: false });
1399 self.convert_event(event, results, errors);
1400 }
1401 }
1402 JsonLdExpansionState::Index => {
1403 if let JsonEvent::String(_) = event {
1404 } else {
1406 errors.push(JsonLdSyntaxError::msg_and_code(
1407 "@index value must be a string",
1408 JsonLdErrorCode::InvalidIndexValue,
1409 ));
1410 self.state
1411 .push(JsonLdExpansionState::Skip { is_array: false });
1412 self.convert_event(event, results, errors);
1413 }
1414 }
1415 JsonLdExpansionState::Graph => {
1416 results.push(JsonLdEvent::EndGraph);
1417 self.convert_event(event, results, errors)
1418 }
1419 JsonLdExpansionState::RootGraph => match event {
1420 JsonEvent::ObjectKey(key) => {
1421 errors.push(JsonLdSyntaxError::msg_and_code(
1422 format!(
1423 "@graph must be the last property of the object, found {key} after it"
1424 ),
1425 JsonLdErrorCode::InvalidStreamingKeyOrder,
1426 ));
1427 self.state.push(JsonLdExpansionState::RootGraph);
1428 self.state
1429 .push(JsonLdExpansionState::Skip { is_array: false });
1430 }
1431 JsonEvent::EndObject => (),
1432 _ => unreachable!(),
1433 },
1434 JsonLdExpansionState::ListOrSetContainer {
1435 needs_end_object,
1436 end_event,
1437 } => {
1438 if needs_end_object {
1439 match event {
1440 JsonEvent::EndObject => {
1441 results.extend(end_event);
1442 self.pop_context();
1443 }
1444 JsonEvent::ObjectKey(key) => {
1445 self.state.push(JsonLdExpansionState::ListOrSetContainer {
1446 needs_end_object,
1447 end_event,
1448 });
1449 if let Some(iri) =
1450 self.expand_iri(key.as_ref().into(), false, true, errors)
1451 {
1452 if iri == "@index" {
1453 self.state.push(JsonLdExpansionState::Index);
1454 } else {
1455 errors.push(JsonLdSyntaxError::msg_and_code(
1456 format!(
1457 "@list must be the only key of an object, {key} found"
1458 ),
1459 JsonLdErrorCode::InvalidSetOrListObject,
1460 ));
1461 self.state
1462 .push(JsonLdExpansionState::Skip { is_array: false });
1463 }
1464 } else {
1465 self.state
1466 .push(JsonLdExpansionState::Skip { is_array: false });
1467 }
1468 }
1469 _ => unreachable!(),
1470 }
1471 } else {
1472 results.extend(end_event);
1473 self.convert_event(event, results, errors)
1474 }
1475 }
1476 JsonLdExpansionState::IndexContainer { active_property } => match event {
1477 JsonEvent::EndObject => (),
1478 JsonEvent::ObjectKey(_) => {
1479 self.state.push(JsonLdExpansionState::IndexContainer {
1481 active_property: active_property.clone(),
1482 });
1483 self.state.push(JsonLdExpansionState::Element {
1484 active_property,
1485 is_array: false,
1486 container: &[],
1487 reverse: false,
1488 })
1489 }
1490 _ => unreachable!(),
1491 },
1492 JsonLdExpansionState::LanguageContainer => match event {
1493 JsonEvent::EndObject => (),
1494 JsonEvent::ObjectKey(language) => {
1495 self.state.push(JsonLdExpansionState::LanguageContainer);
1496 self.state
1497 .push(JsonLdExpansionState::LanguageContainerValue {
1498 language: language.into(),
1499 is_array: false,
1500 })
1501 }
1502 _ => unreachable!(),
1503 },
1504 JsonLdExpansionState::LanguageContainerValue { language, is_array } => match event {
1505 JsonEvent::Null => {
1506 if is_array {
1507 self.state
1508 .push(JsonLdExpansionState::LanguageContainerValue {
1509 language,
1510 is_array,
1511 });
1512 }
1513 }
1514 JsonEvent::String(value) => {
1515 if is_array {
1516 self.state
1517 .push(JsonLdExpansionState::LanguageContainerValue {
1518 language: language.clone(),
1519 is_array,
1520 });
1521 }
1522 results.push(JsonLdEvent::Value {
1523 value: JsonLdValue::String(value.into()),
1524 r#type: None,
1525 language: (language != "@none").then_some(language),
1526 })
1527 }
1528 JsonEvent::StartArray => {
1529 self.state
1530 .push(JsonLdExpansionState::LanguageContainerValue {
1531 language,
1532 is_array: true,
1533 });
1534 if is_array {
1535 errors.push(JsonLdSyntaxError::msg_and_code(
1536 "The values in a @language map must be null or strings",
1537 JsonLdErrorCode::InvalidLanguageMapValue,
1538 ));
1539 self.state
1540 .push(JsonLdExpansionState::Skip { is_array: true })
1541 }
1542 }
1543 JsonEvent::EndArray => (),
1544 _ => {
1545 if is_array {
1546 self.state
1547 .push(JsonLdExpansionState::LanguageContainerValue {
1548 language,
1549 is_array,
1550 });
1551 }
1552 errors.push(JsonLdSyntaxError::msg_and_code(
1553 "The values in a @language map must be null or strings",
1554 JsonLdErrorCode::InvalidLanguageMapValue,
1555 ));
1556 self.state
1557 .push(JsonLdExpansionState::Skip { is_array: false });
1558 self.convert_event(event, results, errors);
1559 }
1560 },
1561 JsonLdExpansionState::Skip { is_array } => match event {
1562 JsonEvent::String(_)
1563 | JsonEvent::Number(_)
1564 | JsonEvent::Boolean(_)
1565 | JsonEvent::Null => {
1566 if is_array {
1567 self.state.push(JsonLdExpansionState::Skip { is_array });
1568 }
1569 }
1570 JsonEvent::EndArray | JsonEvent::EndObject => (),
1571 JsonEvent::StartArray => {
1572 if is_array {
1573 self.state.push(JsonLdExpansionState::Skip { is_array });
1574 }
1575 self.state
1576 .push(JsonLdExpansionState::Skip { is_array: true });
1577 }
1578 JsonEvent::StartObject => {
1579 if is_array {
1580 self.state.push(JsonLdExpansionState::Skip { is_array });
1581 }
1582 self.state
1583 .push(JsonLdExpansionState::Skip { is_array: false });
1584 }
1585 JsonEvent::ObjectKey(_) => {
1586 self.state
1587 .push(JsonLdExpansionState::Skip { is_array: false });
1588 self.state
1589 .push(JsonLdExpansionState::Skip { is_array: false });
1590 }
1591 JsonEvent::Eof => unreachable!(),
1592 },
1593 }
1594 }
1595
1596 fn expand_iri<'a>(
1598 &mut self,
1599 value: Cow<'a, str>,
1600 document_relative: bool,
1601 vocab: bool,
1602 errors: &mut Vec<JsonLdSyntaxError>,
1603 ) -> Option<Cow<'a, str>> {
1604 self.context_processor.expand_iri(
1605 &mut self
1606 .context
1607 .last_mut()
1608 .expect("The context stack must not be empty")
1609 .0,
1610 value,
1611 document_relative,
1612 vocab,
1613 None,
1614 &mut HashMap::new(),
1615 errors,
1616 )
1617 }
1618
1619 fn on_literal_value(
1620 &mut self,
1621 value: JsonLdValue,
1622 active_property: Option<String>,
1623 is_array: bool,
1624 container: &'static [&'static str],
1625 reverse: bool,
1626 results: &mut Vec<JsonLdEvent>,
1627 errors: &mut Vec<JsonLdSyntaxError>,
1628 ) {
1629 if !is_array {
1630 if container.contains(&"@list") {
1631 if reverse {
1632 errors.push(JsonLdSyntaxError::msg_and_code(
1633 "Lists are not allowed inside of reverse properties",
1634 JsonLdErrorCode::InvalidReversePropertyValue,
1635 ))
1636 }
1637 results.push(JsonLdEvent::StartList);
1638 } else if container.contains(&"@set") {
1639 results.push(JsonLdEvent::StartSet);
1640 }
1641 }
1642 if let Some(active_property) = &active_property {
1643 self.expand_value(active_property, value, reverse, results, errors);
1644 }
1645 if is_array {
1646 self.state.push(JsonLdExpansionState::Element {
1647 active_property,
1648 is_array,
1649 container,
1650 reverse,
1651 });
1652 } else if container.contains(&"@list") {
1653 results.push(JsonLdEvent::EndList);
1654 } else if container.contains(&"@set") {
1655 results.push(JsonLdEvent::EndSet);
1656 }
1657 }
1658
1659 fn expand_value(
1661 &mut self,
1662 active_property: &str,
1663 value: JsonLdValue,
1664 reverse: bool,
1665 results: &mut Vec<JsonLdEvent>,
1666 errors: &mut Vec<JsonLdSyntaxError>,
1667 ) {
1668 let active_context = self.context();
1669 let mut r#type = None;
1670 let mut language = None;
1671 if let Some(term_definition) = active_context.term_definitions.get(active_property) {
1672 if let Some(type_mapping) = &term_definition.type_mapping {
1673 match type_mapping.as_ref() {
1674 "@id" => {
1676 if let JsonLdValue::String(value) = value {
1677 if let Some(id) = self.expand_iri(value.into(), true, false, errors) {
1678 results.push(JsonLdEvent::StartObject { types: Vec::new() });
1679 results.push(JsonLdEvent::Id(id.into()));
1680 results.push(JsonLdEvent::EndObject);
1681 }
1682 return;
1683 }
1684 }
1685 "@vocab" => {
1687 if let JsonLdValue::String(value) = value {
1688 if let Some(id) = self.expand_iri(value.into(), true, true, errors) {
1689 results.push(JsonLdEvent::StartObject { types: Vec::new() });
1690 results.push(JsonLdEvent::Id(id.into()));
1691 results.push(JsonLdEvent::EndObject);
1692 }
1693 return;
1694 }
1695 }
1696 "@none" => (),
1698 _ => {
1699 r#type = Some(type_mapping.clone());
1700 }
1701 }
1702 }
1703 if matches!(value, JsonLdValue::String(_)) {
1705 language = term_definition
1706 .language_mapping
1707 .clone()
1708 .unwrap_or_else(|| active_context.default_language.clone());
1709 }
1710 } else {
1711 if matches!(value, JsonLdValue::String(_)) && language.is_none() {
1713 language.clone_from(&active_context.default_language);
1714 }
1715 }
1716 if reverse {
1717 errors.push(JsonLdSyntaxError::msg_and_code(
1718 "Literals are not allowed inside of reverse properties",
1719 JsonLdErrorCode::InvalidReversePropertyValue,
1720 ))
1721 }
1722 results.push(JsonLdEvent::Value {
1723 value,
1724 r#type,
1725 language,
1726 });
1727 }
1728
1729 pub fn context(&self) -> &JsonLdContext {
1730 &self
1731 .context
1732 .last()
1733 .expect("The context stack must not be empty")
1734 .0
1735 }
1736
1737 fn push_same_context(&mut self) {
1738 self.context
1739 .last_mut()
1740 .expect("The context stack must not be empty")
1741 .1 += 1;
1742 }
1743
1744 fn push_new_context(
1745 &mut self,
1746 context: Vec<JsonEvent<'static>>,
1747 errors: &mut Vec<JsonLdSyntaxError>,
1748 ) {
1749 let context = self.context_processor.process_context(
1750 self.context(),
1751 json_node_from_events(context.into_iter().map(Ok)).unwrap(),
1752 self.base_url.as_ref(),
1753 &mut Vec::new(),
1754 false,
1755 true,
1756 true,
1757 errors,
1758 );
1759 if let Some((last_context, last_count)) = self.context.pop() {
1760 if last_count > 1 {
1761 self.context.push((last_context, last_count - 1));
1762 }
1763 }
1764 self.context.push((context, 1));
1765 }
1766
1767 fn pop_context(&mut self) {
1768 let Some((last_context, mut last_count)) = self.context.pop() else {
1769 return;
1770 };
1771 last_count -= 1;
1772 if last_count > 0 || self.context.is_empty() {
1773 self.context.push((last_context, last_count));
1775 }
1776 }
1777}
1778
1779fn to_owned_event(event: JsonEvent<'_>) -> JsonEvent<'static> {
1780 match event {
1781 JsonEvent::String(s) => JsonEvent::String(Cow::Owned(s.into())),
1782 JsonEvent::Number(n) => JsonEvent::Number(Cow::Owned(n.into())),
1783 JsonEvent::Boolean(b) => JsonEvent::Boolean(b),
1784 JsonEvent::Null => JsonEvent::Null,
1785 JsonEvent::StartArray => JsonEvent::StartArray,
1786 JsonEvent::EndArray => JsonEvent::EndArray,
1787 JsonEvent::StartObject => JsonEvent::StartObject,
1788 JsonEvent::EndObject => JsonEvent::EndObject,
1789 JsonEvent::ObjectKey(k) => JsonEvent::ObjectKey(Cow::Owned(k.into())),
1790 JsonEvent::Eof => JsonEvent::Eof,
1791 }
1792}