Skip to main content

json_ld/syntax/context/definition/
mod.rs

1use crate::{
2	JsonLdLenient,
3	syntax::{JsonLdDirection, JsonLdKeyword, JsonLdNullable},
4};
5use btree_indexmap::BTreeIndexMap;
6use langtag::LangTagBuf;
7use rdf_syntax::IriRefBuf;
8
9mod reference;
10mod term;
11mod type_;
12mod version;
13mod vocab;
14
15pub use reference::*;
16pub use term::*;
17pub use type_::*;
18pub use version::*;
19pub use vocab::*;
20
21/// Context definition.
22#[derive(Default, PartialEq, Eq, Clone, Debug)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub struct JsonLdContextDefinition {
25	#[cfg_attr(
26		feature = "serde",
27		serde(
28			rename = "@base",
29			default,
30			deserialize_with = "JsonLdNullable::optional",
31			skip_serializing_if = "Option::is_none"
32		)
33	)]
34	pub base: Option<JsonLdNullable<IriRefBuf>>,
35
36	#[cfg_attr(
37		feature = "serde",
38		serde(rename = "@import", default, skip_serializing_if = "Option::is_none")
39	)]
40	pub import: Option<IriRefBuf>,
41
42	#[cfg_attr(
43		feature = "serde",
44		serde(
45			rename = "@language",
46			default,
47			deserialize_with = "JsonLdNullable::optional",
48			skip_serializing_if = "Option::is_none"
49		)
50	)]
51	pub language: Option<JsonLdNullable<JsonLdLenient<LangTagBuf>>>,
52
53	#[cfg_attr(
54		feature = "serde",
55		serde(
56			rename = "@direction",
57			default,
58			deserialize_with = "JsonLdNullable::optional",
59			skip_serializing_if = "Option::is_none"
60		)
61	)]
62	pub direction: Option<JsonLdNullable<JsonLdDirection>>,
63
64	#[cfg_attr(
65		feature = "serde",
66		serde(
67			rename = "@propagate",
68			default,
69			skip_serializing_if = "Option::is_none"
70		)
71	)]
72	pub propagate: Option<bool>,
73
74	#[cfg_attr(
75		feature = "serde",
76		serde(
77			rename = "@protected",
78			default,
79			skip_serializing_if = "Option::is_none"
80		)
81	)]
82	pub protected: Option<bool>,
83
84	#[cfg_attr(
85		feature = "serde",
86		serde(rename = "@type", default, skip_serializing_if = "Option::is_none")
87	)]
88	pub type_: Option<JsonLdContextType>,
89
90	#[cfg_attr(
91		feature = "serde",
92		serde(rename = "@version", default, skip_serializing_if = "Option::is_none")
93	)]
94	pub version: Option<JsonLdVersion>,
95
96	#[cfg_attr(
97		feature = "serde",
98		serde(
99			rename = "@vocab",
100			default,
101			deserialize_with = "JsonLdNullable::optional",
102			skip_serializing_if = "Option::is_none"
103		)
104	)]
105	pub vocab: Option<JsonLdNullable<JsonLdVocab>>,
106
107	#[cfg_attr(feature = "serde", serde(flatten))]
108	pub bindings: JsonLdContextBindings,
109}
110
111impl JsonLdContextDefinition {
112	pub fn new() -> Self {
113		Self::default()
114	}
115
116	pub fn get(&self, key: &JsonLdKeyOrKeyword) -> Option<JsonLdContextEntryValueRef<'_>> {
117		match key {
118			JsonLdKeyOrKeyword::Keyword(k) => match k {
119				JsonLdKeyword::Base => self
120					.base
121					.as_ref()
122					.map(JsonLdNullable::as_deref)
123					.map(JsonLdContextEntryValueRef::Base),
124				JsonLdKeyword::Import => self
125					.import
126					.as_deref()
127					.map(JsonLdContextEntryValueRef::Import),
128				JsonLdKeyword::Language => self
129					.language
130					.as_ref()
131					.map(JsonLdNullable::as_ref)
132					.map(JsonLdContextEntryValueRef::Language),
133				JsonLdKeyword::Direction => {
134					self.direction.map(JsonLdContextEntryValueRef::Direction)
135				}
136				JsonLdKeyword::Propagate => {
137					self.propagate.map(JsonLdContextEntryValueRef::Propagate)
138				}
139				JsonLdKeyword::Protected => {
140					self.protected.map(JsonLdContextEntryValueRef::Protected)
141				}
142				JsonLdKeyword::Type => self.type_.map(JsonLdContextEntryValueRef::Type),
143				JsonLdKeyword::Version => self.version.map(JsonLdContextEntryValueRef::Version),
144				JsonLdKeyword::Vocab => self
145					.vocab
146					.as_ref()
147					.map(JsonLdNullable::as_ref)
148					.map(JsonLdContextEntryValueRef::Vocab),
149				_ => None,
150			},
151			JsonLdKeyOrKeyword::Key(k) => self
152				.bindings
153				.get(k)
154				.map(JsonLdContextEntryValueRef::Definition),
155		}
156	}
157
158	pub fn get_binding(
159		&self,
160		key: &JsonLdContextTerm,
161	) -> Option<JsonLdNullable<&JsonLdTermDefinition>> {
162		self.bindings.get(key)
163	}
164}
165
166/// Context bindings.
167#[derive(Default, PartialEq, Eq, Clone, Debug)]
168#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
169#[cfg_attr(feature = "serde", serde(transparent))]
170pub struct JsonLdContextBindings(
171	BTreeIndexMap<JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>>,
172);
173
174pub struct JsonLdContextBindingsIter<'a>(
175	btree_indexmap::map::Iter<'a, JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>>,
176);
177
178impl<'a> Iterator for JsonLdContextBindingsIter<'a> {
179	type Item = (
180		&'a JsonLdContextTerm,
181		JsonLdNullable<&'a JsonLdTermDefinition>,
182	);
183
184	fn next(&mut self) -> Option<Self::Item> {
185		self.0.next().map(|(k, d)| (k, d.as_ref()))
186	}
187}
188
189impl<'a> DoubleEndedIterator for JsonLdContextBindingsIter<'a> {
190	fn next_back(&mut self) -> Option<Self::Item> {
191		self.0.next_back().map(|(k, d)| (k, d.as_ref()))
192	}
193}
194
195impl<'a> ExactSizeIterator for JsonLdContextBindingsIter<'a> {}
196
197impl JsonLdContextBindings {
198	pub fn insert(
199		&mut self,
200		key: JsonLdContextTerm,
201		def: JsonLdNullable<JsonLdTermDefinition>,
202	) -> Option<JsonLdNullable<JsonLdTermDefinition>> {
203		self.0.insert(key, def)
204	}
205}
206
207impl JsonLdContextBindings {
208	pub fn new() -> Self {
209		Self::default()
210	}
211
212	pub fn len(&self) -> usize {
213		self.0.len()
214	}
215
216	pub fn is_empty(&self) -> bool {
217		self.0.is_empty()
218	}
219
220	pub fn get(&self, key: &JsonLdContextTerm) -> Option<JsonLdNullable<&JsonLdTermDefinition>> {
221		self.0.get(key).map(JsonLdNullable::as_ref)
222	}
223
224	pub fn get_entry(
225		&self,
226		i: usize,
227	) -> Option<(&JsonLdContextTerm, JsonLdNullable<&JsonLdTermDefinition>)> {
228		self.0
229			.as_entries()
230			.get(i)
231			.map(|(key, value)| (key, value.as_ref()))
232	}
233
234	pub fn iter(&self) -> JsonLdContextBindingsIter<'_> {
235		JsonLdContextBindingsIter(self.0.iter())
236	}
237
238	pub fn insert_with(
239		&mut self,
240		key: JsonLdContextTerm,
241		def: JsonLdNullable<JsonLdTermDefinition>,
242	) -> Option<JsonLdNullable<JsonLdTermDefinition>> {
243		self.0.insert(key, def)
244	}
245}
246
247impl IntoIterator for JsonLdContextBindings {
248	type Item = (JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>);
249	type IntoIter =
250		btree_indexmap::map::IntoIter<JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>>;
251
252	fn into_iter(self) -> Self::IntoIter {
253		self.0.into_iter()
254	}
255}
256
257impl FromIterator<(JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>)>
258	for JsonLdContextBindings
259{
260	fn from_iter<
261		T: IntoIterator<Item = (JsonLdContextTerm, JsonLdNullable<JsonLdTermDefinition>)>,
262	>(
263		iter: T,
264	) -> Self {
265		let mut result = Self::new();
266
267		for (key, binding) in iter {
268			result.0.insert(key, binding);
269		}
270
271		result
272	}
273}