json_ld_core/document/
mod.rs

1use std::ops::Deref;
2use std::{borrow::Borrow, hash::Hash};
3
4use iref::IriBuf;
5use linked_data::{LinkedData, LinkedDataGraph, LinkedDataResource, LinkedDataSubject};
6use rdf_types::{vocabulary::IriVocabularyMut, BlankIdBuf, Interpretation, Vocabulary};
7
8pub mod expanded;
9pub mod flattened;
10
11pub use expanded::ExpandedDocument;
12pub use flattened::FlattenedDocument;
13
14use crate::RemoteDocument;
15
16/// JSON-LD document in both compact and expanded form.
17#[derive(Debug, Clone)]
18pub struct Document<I = IriBuf, B = BlankIdBuf> {
19	remote: RemoteDocument<I>,
20	expanded: ExpandedDocument<I, B>,
21}
22
23impl<I, B> Document<I, B> {
24	pub fn new(remote: RemoteDocument<I>, expanded: ExpandedDocument<I, B>) -> Self {
25		Self { remote, expanded }
26	}
27
28	pub fn into_remote(self) -> RemoteDocument<I> {
29		self.remote
30	}
31
32	pub fn into_compact(self) -> json_ld_syntax::Value {
33		self.remote.into_document()
34	}
35
36	pub fn into_expanded(self) -> ExpandedDocument<I, B> {
37		self.expanded
38	}
39
40	#[allow(clippy::type_complexity)]
41	pub fn into_parts(self) -> (RemoteDocument<I>, ExpandedDocument<I, B>) {
42		(self.remote, self.expanded)
43	}
44
45	pub fn as_remote(&self) -> &RemoteDocument<I> {
46		&self.remote
47	}
48
49	pub fn as_compact(&self) -> &json_ld_syntax::Value {
50		self.remote.document()
51	}
52
53	pub fn as_expanded(&self) -> &ExpandedDocument<I, B> {
54		&self.expanded
55	}
56}
57
58impl<I, B> Deref for Document<I, B> {
59	type Target = ExpandedDocument<I, B>;
60
61	fn deref(&self) -> &Self::Target {
62		&self.expanded
63	}
64}
65
66impl<I, B> Borrow<RemoteDocument<I>> for Document<I, B> {
67	fn borrow(&self) -> &RemoteDocument<I> {
68		&self.remote
69	}
70}
71
72impl<I, B> Borrow<json_ld_syntax::Value> for Document<I, B> {
73	fn borrow(&self) -> &json_ld_syntax::Value {
74		self.remote.document()
75	}
76}
77
78impl<I, B> Borrow<ExpandedDocument<I, B>> for Document<I, B> {
79	fn borrow(&self) -> &ExpandedDocument<I, B> {
80		&self.expanded
81	}
82}
83
84impl<I: Eq + Hash, B: Eq + Hash> PartialEq for Document<I, B> {
85	fn eq(&self, other: &Self) -> bool {
86		self.expanded.eq(&other.expanded)
87	}
88}
89
90impl<I: Eq + Hash, B: Eq + Hash> Eq for Document<I, B> {}
91
92#[cfg(feature = "serde")]
93impl<I, B> serde::Serialize for Document<I, B> {
94	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
95	where
96		S: serde::Serializer,
97	{
98		self.remote.document().serialize(serializer)
99	}
100}
101
102impl<V: Vocabulary, I: Interpretation> LinkedData<I, V> for Document<V::Iri, V::BlankId>
103where
104	V: IriVocabularyMut,
105	V::Iri: LinkedDataSubject<I, V> + LinkedDataResource<I, V>,
106	V::BlankId: LinkedDataSubject<I, V> + LinkedDataResource<I, V>,
107{
108	fn visit<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
109	where
110		S: linked_data::Visitor<I, V>,
111	{
112		self.expanded.visit(visitor)
113	}
114}
115
116impl<V: Vocabulary, I: Interpretation> LinkedDataGraph<I, V> for Document<V::Iri, V::BlankId>
117where
118	V: IriVocabularyMut,
119	V::Iri: LinkedDataSubject<I, V> + LinkedDataResource<I, V>,
120	V::BlankId: LinkedDataSubject<I, V> + LinkedDataResource<I, V>,
121{
122	fn visit_graph<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
123	where
124		S: linked_data::GraphVisitor<I, V>,
125	{
126		self.expanded.visit_graph(visitor)
127	}
128}